如何在Swift中使用CFArrayRef?

我在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>甚至意味着什么?

我看通过如何将CFArray转换为Swift数组? 但我不需要将数组转换为一个快速数组(但是,这将是很好的)。 我只需要能够从数组中获取值。

我也尝试了将CFArray传递给此答案中概述的函数的方法:

 func doSomeStuffOnArray(myArray: NSArray) { } 

不过,使用它时会出现类似的错误:

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

我正在使用CFArray因为我需要存储一个CGPathRef数组,不能存储在NSArray

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

正如使用Cocoa数据types所解释的那样,当您从Swift中导入的函数中返回Core Foundation对象时,有两种可能的解决scheme:

  • 使用CF_RETURNS_RETAINEDCF_RETURNS_NOT_RETAINED注释该函数。 在你的情况下:

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

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

Unmanaged是实际CF值的包装。 (有点像一个可选的)。它是在那里,因为ARC不能从someMethod:的声明someMethod:这个方法是否保留了它返回的值。

通过告诉ARC使用什么内存pipe理策略来为内部的值打开Unmanaged 。 如果someMethod在其返回值上调用CFRetain

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

如果没有:

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

这样做后, cfArr是一个CFArray ,所以你可以使用桥接技巧从你链接的其他问题来访问它像一个Swift数组。

如果你拥有someMethod的代码,你可以改变一下,不需要这个。 有几个select:

  • CF_RETURNS_RETAINEDCF_RETURNS_NOT_RETAINED注释告诉编译器需要什么内存行为
  • 由于它是一个ObjC方法,所以桥接到NSArray并返回 – [AnyObject]自动成为Swift中的[AnyObject]数组。