如何在Swift中使用CFArrayRef?

时间:2014-07-26 15:57:41

标签: ios objective-c arrays swift

我通过桥接头在我的Swift项目中使用Objective-C类。方法签名看起来像这样:

- (CFArrayRef)someMethod:(someType)someParameter;

我首先获取类的实例,调用方法并存储值:

var myInstance = MyClassWithThatMethod();
var cfArr = myInstance.someMethod(someValue);

然后尝试在数组中获取一个值:

var valueInArrayThatIWant = CFArrayGetValueAtIndex(cfArr, 0);

但是我收到错误Unmanaged<CFArray>' is not identical to 'CFArray'Unmanaged<CFArray>甚至意味着什么?

我浏览了How to convert CFArray to Swift Array?,但我不需要将数组转换为快速数组(但这样会很好)。我只需要能够从数组中获取值。

我也尝试过将CFArray传递给概述in this answer的函数的方法:

func doSomeStuffOnArray(myArray: NSArray) {

}

但是我在使用它时遇到类似的错误:

doSomeStuffOnArray(cfArr); // Unmanaged<CFArray>' is not identical to 'NSArray'

我正在使用CFArray,因为我需要存储CGPathRef的数组,该数组无法存储在NSArray中。

那么我应该如何在Swift中使用CFArray

2 个答案:

答案 0 :(得分:8)

如中所述 Working with Core Foundation Types,有两种可能的解决方案 您从自己的函数返回Core Foundation对象,该函数是在Swift中导入的:

  • 使用CF_RETURNS_RETAINEDCF_RETURNS_NOT_RETAINED注释该功能。 在你的情况下:

    - (CFArrayRef)someMethod:(someType)someParameter CF_RETURNS_NOT_RETAINED;
    
  • 或者将非托管对象转换为Swift中takeUnretainedValue()takeRetainedValue()的内存托管对象。在你的情况下:

    var cfArr = myInstance.someMethod(someValue).takeUnretainedValue()
    

答案 1 :(得分:1)

Unmanaged是实际CF值的包装器。 (类似于一个可选项。)它是因为ARC无法通过查看someMethod:的声明来判断该方法是否保留了它返回的值。

通过告诉ARC用于内部值的内存管理策略来解包Unmanaged。如果someMethod在其返回值上调用CFRetain

let cfArr = myInstance.someMethod(someValue).takeRetainedValue()

如果它没有:

let cfArr = myInstance.someMethod(someValue).takeUnretainedValue()

执行此操作后,cfArrCFArray,因此您可以使用链接到的其他问题的桥接技巧来访问它,就像Swift数组一样。

如果您拥有someMethod的代码,则可以稍微更改一下,不需要此代码。有几种选择:

  • 使用CF_RETURNS_RETAINEDCF_RETURNS_NOT_RETAINED进行批注,告诉编译器需要哪些内存行为
  • 由于它是一个ObjC方法,桥接到NSArray并返回 - 它将自动成为Swift中的[AnyObject]数组。