如何在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_RETAINED
或CF_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_RETAINED
或CF_RETURNS_NOT_RETAINED
注释告诉编译器需要什么内存行为 - 由于它是一个ObjC方法,所以桥接到
NSArray
并返回 –[AnyObject]
自动成为Swift中的[AnyObject]
数组。