【问题标题】:CFURLCreateDataAndPropertiesFromResource deprecated. And looking for substituteCFURLCreateDataAndPropertiesFromResource 已弃用。并寻找替代品
【发布时间】:2013-09-26 05:30:34
【问题描述】:

除了 Apple 的 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;

【问题讨论】:

    标签: ios xcode macos core-foundation


    【解决方案1】:

    对于属性: CFURLCopyResourcePropertiesForKeys 示例属性:kCFURLFileSizeKey 和 kCFURLContentModificationDateKey,或带有 [NSURL resourceValuesForKeys:error:] 的 Foundation 样式。

    数据:+[NSData dataWithContentsOfURL:options:error:]。

    他们没有记录为替代品,AFAIK。这些更新的替代 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 代替返回的代码一个布尔值。
    • 我开始拍照片了,这很有帮助。所以我猜 CFPropertyListCreateWithData 现在必须替换为使用 NSData 对象的东西?目前,由于 propertyResourceData 仍然为 0,NSAssert 失败。
    • @stugrimshaw NSData 和 CFData 是同一类型——只是不同语言的名称不同。请参阅:免费桥接。这允许您使用简单的类型转换将 NSData 用作 CFData(或相反)。该 API 只是第一个想到的用于在一行中完成此任务的 API。
    【解决方案2】:

    我发现只使用以下代码可以删除更多代码:

    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;
    

    【讨论】:

      【解决方案3】:

      我最终使用了这个代码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;
      

      【讨论】:

        猜你喜欢
        • 2019-03-24
        • 2013-04-28
        • 1970-01-01
        • 2023-03-20
        • 2016-05-25
        • 2015-06-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多