我通过桥接头在我的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
?
答案 0 :(得分:8)
如中所述 Working with Core Foundation Types,有两种可能的解决方案 您从自己的函数返回Core Foundation对象,该函数是在Swift中导入的:
使用CF_RETURNS_RETAINED
或CF_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()
执行此操作后,cfArr
为CFArray
,因此您可以使用链接到的其他问题的桥接技巧来访问它,就像Swift数组一样。
如果您拥有someMethod
的代码,则可以稍微更改一下,不需要此代码。有几种选择:
CF_RETURNS_RETAINED
或CF_RETURNS_NOT_RETAINED
进行批注,告诉编译器需要哪些内存行为NSArray
并返回 - 它将自动成为Swift中的[AnyObject]
数组。