如何将 CFArray 转换为 Swift 数组? [英] How to convert CFArray to Swift Array?

查看:68
本文介绍了如何将 CFArray 转换为 Swift 数组?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据 Apple 的将 Swift 与 Cocoa 和 Objective-C 结合使用",在 Swift 中,您可以互换使用每对免费桥接的 Foundation 和 Core Foundation 类型".这使得使用 Core Foundation 听起来比实际更简单...

According to Apple's "Using Swift with Cocoa and Objective-C", "In Swift, you can use each pair of toll-free bridged Foundation and Core Foundation types interchangeably". This makes working with Core Foundation sound way simpler than it actually is...

我正在尝试使用从 CoreText 返回的 CFArray.我有这个代码:

I am trying to work with a CFArray that is returned from CoreText. I have this code:

let lines: CFArrayRef  = CTFrameGetLines(frame)

我看到了两种可能的方法来访问这个数组的成员.现在两者都不适合我.

I see two possible ways to access members of this array. Neither is working for me right now.

方法 #1 - 直接使用 CFArray

Way #1 - Use the CFArray directly

let line: CTLineRef = CFArrayGetValueAtIndex(lines, 0)

这会产生错误'ConstUnsafePointer<()>' in not convertible to 'CTLineRef'".投射似乎并没有改变这个错误.

This yields the error "'ConstUnsafePointer<()>' in not convertible to 'CTLineRef'". Casting does not seem to change this error.

同样,我很乐意将行可互换地"用作 Swift 数组,就像它说的那样.然而,

Similarly, I would love to use lines "interchangeably" as a Swift array like it says that I can. However,

let line: CTLineRef = lines[0]

产生错误'CFArrayRef'没有名为'subscript'的成员"

yields the error "'CFArrayRef' does not have a member named 'subscript'"

方法 #2 - 将 CFArray 转换为 Swift 数组

Way #2 - Convert the CFArray to a Swift array

var linesArray: Array = [CTLineRef]()
linesArray = bridgeFromObjectiveC(lines, linesArray.dynamicType)

在这里,我声明了一个 Swift 数组并将其设置为桥接的 CFArray.这编译没有错误,但是当我运行它时,我在第二行遇到 EXC_BREAKPOINT 崩溃.也许我在这方面没有正确使用 Swift 语言...

Here, I declared a Swift array and set it equal to the bridged CFArray. This compiles without error, but when I run it, I get an EXC_BREAKPOINT crash on the second line. Perhaps I'm not using the Swift language correctly on this one...

推荐答案

以下是根据 Swift 编译器和 Swift 文档的当前状态执行此操作的方法.希望这会在以后的测试版中得到解决.

Here is how to do this, based on the current state of the Swift compiler and Swift documentation. Hopefully this gets cleaned up in later betas.

更新:从 Beta 5 开始,reinterpretCast 已重命名为 unsafeBitCast,并且必须将 CTLine 对象作为输入发送给它.方法 #2 仍然不起作用.

UPDATE: Since Beta 5, reinterpretCast has been renamed to unsafeBitCast, and a CTLine object must be sent to it as an input. Way #2 still does not work.

方法 #1 - 直接使用 CFArray

Way #1 - Use the CFArray directly

let line: CTLine = reinterpretCast(CFArrayGetValueAtIndex(lines, 0))

关于 Gary Makin 的评论 - 可以从 CTLineRef 中删除 Ref,但这不会改变 ARC 与非 ARC.根据在 Cocoa 和 Objective-C 中使用 Swift 第 53-54 页,ref 和 non-ref 与编译器相同.尝试调用 CFRelease 会导致编译器错误.

Regarding Gary Makin's comments - The Ref can be dropped from CTLineRef, but this does not change ARC vs non-ARC. According to Using Swift with Cocoa and Objective-C pages 53-54, ref and non-ref are identical to the compiler. Attempting to call CFRelease causes a compiler error.

方法 #2 - 将 CFArray 转换为 Swift 数组 - 目前不起作用

Way #2 - Convert the CFArray to a Swift array - Does not currently work

理想情况下,我们希望将行转换为 CTLine 对象的 Swift 数组,因为我们知道 CTFrameGetLines 返回的内容,从而在转换后为我们提供类型安全.可能由于编译器错误,该数组可以转换为 [AnyObject] 数组,但不能转换为 [CTLine].根据 Apple 的文档,这应该有效:

Ideally, we want to convert lines to a Swift array of CTLine objects since we know that's what is returned by CTFrameGetLines, giving us type safety after the conversion. Probably due to a compiler bug, the array can be converted to an [AnyObject] array, but not to [CTLine]. According to Apple's documentation, this should work:

let linesNS: NSArray  = CTFrameGetLines(frame)
let linesAO: [AnyObject] = linesNS as [AnyObject]
let lines: [CTLine] = linesAO as [CTLine]

这会将 CFArray 转换为 NSArray,然后将 NSArray 转换为 Swift Array [AnyObject],然后将该数组向下转换为特定类型的 CTLine.这编译了,但是当它运行时,在最后一行有一个 EXC_BREAKPOINT 崩溃.

This converts CFArray to NSArray, then NSArray to Swift Array [AnyObject], then downcasts that array to the specific type CTLine. This compiles, but when it is run, there is an EXC_BREAKPOINT crash on the last line.

这篇关于如何将 CFArray 转换为 Swift 数组?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆