CFURLCreateDataAndPropertiesFromResource被弃用。正在寻找替代方法。

3

随着苹果公司的Load Preset Demo示例代码中包含的其他内容,调用CFURLCreateDataAndPropertiesFromResource现已过时。但我找不到它的替代品 - 无论是选项点击还是查看参考资料都没有告诉我更多信息,只是这不再是推荐的做法。

CFDataRef propertyResourceData = 0;
Boolean status;
SInt32 errorCode = 0;
OSStatus result = noErr;

// Read from the URL and convert into a CFData chunk
status = CFURLCreateDataAndPropertiesFromResource (
                                                   kCFAllocatorDefault,
                                                   (__bridge CFURLRef) presetURL,
                                                   &propertyResourceData,
                                                   NULL,
                                                   NULL,
                                                   &errorCode
                                                   );


NSAssert (status == YES && propertyResourceData != 0, @"Unable to create data and properties from a preset. Error code: %d '%.4s'", (int) errorCode, (const char *)&errorCode);

// Convert the data object into a property list
CFPropertyListRef presetPropertyList = 0;
CFPropertyListFormat dataFormat = 0;
CFErrorRef errorRef = 0;
presetPropertyList = CFPropertyListCreateWithData (
                                                   kCFAllocatorDefault,
                                                   propertyResourceData,
                                                   kCFPropertyListImmutable,
                                                   &dataFormat,
                                                   &errorRef
                                                   );

// Set the class info property for the Sampler unit using the property list as the value.
if (presetPropertyList != 0) {

    result = AudioUnitSetProperty(
                                  self.samplerUnit,
                                  kAudioUnitProperty_ClassInfo,
                                  kAudioUnitScope_Global,
                                  0,
                                  &presetPropertyList,
                                  sizeof(CFPropertyListRef)
                                  );

    CFRelease(presetPropertyList);
}

if (errorRef) CFRelease(errorRef);
CFRelease (propertyResourceData);

return result;
3个回答

5

对于属性:使用CFURLCopyResourcePropertiesForKeys,例如属性:kCFURLFileSizeKeykCFURLContentModificationDateKey,或者基于Foundation的方式使用[NSURL resourceValuesForKeys:error:]

对于数据:使用+[NSData dataWithContentsOfURL:options:error:]

据我所知,它们没有被记录为替代方案。这些更新的替换API中大多数已经存在了几年。

编辑

在您发布的此示例中,程序不会请求属性,因此您只需要URL presetURL上的数据。

要实现此目的,可以通过以下方式:

NSURL * presetURL = ...;
// do review these options for your needs. you can make great
// optimizations if you use memory mapping or avoid unnecessary caching.
const NSDataReadingOptions DataReadingOptions = 0;
NSError * outError = nil;
NSData * data = [NSData dataWithContentsOfURL:presetURL
                                      options:DataReadingOptions
                                        error:&outError];

const bool status = nil != data; // << your `status` variable

if (!status) {
 // oops - an error was encountered getting the data see `outError`
}
else {
 // use the data
}

我尝试转换问题中的代码(请参见编辑后的帖子),但是我在这里陌生,不确定如何使用dataWithContentsOfURL:options:error来代替返回布尔值的代码。 - HenryRootTwo
我开始明白了,这帮了很多。所以我猜CFPropertyListCreateWithData现在必须被替换为使用NSData对象的东西?目前NSAssert失败是因为propertyResourceData仍然为0。 - HenryRootTwo
@stugrimshaw NSDataCFData是相同的类型--只是不同语言的不同名称。参见:toll free bridging。这允许您使用简单的类型转换将NSData用作CFData(或反之亦然)。该API只是在脑海中完成此任务的第一个API。 - justin

0
我发现只需使用以下代码,就可以删除更多的代码:
OSStatus result = noErr;
NSData* data = [NSData dataWithContentsOfURL:presetURL];
id propertyList = [NSPropertyListSerialization propertyListWithData:data options:NSPropertyListImmutable format:NULL error:NULL];

// Set the class info property for the Sampler unit using the property list as the value.
if (propertyList) {
    result = AudioUnitSetProperty(
                                  self.samplerUnit,
                                  kAudioUnitProperty_ClassInfo,
                                  kAudioUnitScope_Global,
                                  0,
                                  (__bridge CFPropertyListRef)propertyList,
                                  sizeof(CFPropertyListRef)
                                  );
}

return result;

-1

我最终使用了这段代码 https://developer.apple.com/library/mac/technotes/tn2283/_index.html#//apple_ref/doc/uid/DTS40011217-CH1-TNTAG2

- (OSStatus) loadSynthFromPresetURL: (NSURL *) presetURL {

OSStatus result = noErr;

AUSamplerInstrumentData auPreset = {0};

auPreset.fileURL = (__bridge CFURLRef) presetURL;
auPreset.instrumentType = kInstrumentType_AUPreset;

result = AudioUnitSetProperty(self.samplerUnit,
                              kAUSamplerProperty_LoadInstrument,
                              kAudioUnitScope_Global,
                              0,
                              &auPreset,
                              sizeof(auPreset));

return result;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接