Swift 中 CoreText CTFrameGetLineOrigins 的问题

Posted

技术标签:

【中文标题】Swift 中 CoreText CTFrameGetLineOrigins 的问题【英文标题】:Issue with CoreText CTFrameGetLineOrigins in Swift 【发布时间】:2014-06-26 15:42:41 【问题描述】:

我有以下代码在 Objective-C 中工作

NSArray *lines = (NSArray *)CTFrameGetLines((__bridge CTFrameRef)columnFrame);
CGPoint origins[[lines count]];
CTFrameGetLineOrigins((__bridge CTFrameRef)columnFrame, CFRangeMake(0, 0), origins);

但是当移植到 Swift 时,编译器会在 CTFrameGetLineOrigins 行中抱怨 Cannot convert the expression´s ´Void´to type ´CMutablePointer<CGPoint>

let nsLinesArray: NSArray = CTFrameGetLines(ctFrame) // Use NSArray to bridge to Array
let ctLinesArray = nsLinesArray as Array
var originsArray: Array<CGPoint> = CGPoint[]()
//var originsArray: NSMutableArray = NSMutableArray.array()
let range: CFRange = CFRangeMake(0, 0)
CTFrameGetLineOrigins(ctFrame, range, originsArray)

我不得不在 CGFrameGetLines 函数中使用 NSArray,然后转换为 Swift 数组,并检查 ctLinesArray,显示 CTLine 对象已正确检索

我尝试将NSMutableArray 用于originsArray,结果相同。

知道缺少什么吗?

【问题讨论】:

【参考方案1】:

您必须添加地址运算符&amp; 才能将指针传递给 originsArray 函数的开头:

CTFrameGetLineOrigins(ctFrame, range, &originsArray)

参考:Interacting with C APIs 在“将 Swift 与 Cocoa 和 Objective-C 一起使用”一书中:

C 可变指针

当函数被声明为采用CMutablePointer&lt;Type&gt; 参数,它可以接受以下任何一种:

... 一个输入输出Type[] 值, 它作为指向数组开头的指针传递,并且 在通话期间延长生命周期。

来自《The Swift Programming Language》一书中的Expressions:

除了上面列出的标准库运算符之外,您还可以使用&amp; 紧接在作为变量传递的变量的名称之前 函数调用表达式的输入输出参数。

一个补充(正如@eharo2 已经弄清楚的那样),originsArray 必须有空间容纳 必要数量的元素,可以通过

var originsArray = CGPoint[](count:ctLinesArray.count, repeatedValue: CGPointZero)

【讨论】:

#Martin R. 我已经这样做了,尽管 Objective-C 版本不使用内存地址,但 Swift 文档将 origins 称为缓冲区。这样编译不会报告任何问题,但是我有一个运行时 EXEC_BAD_ACCESS 错误。 @eharo2:好的,我只编译了它。我从文档中添加了一些参考资料,这些参考资料应该解释为什么 &amp; 是正确的。但我无法解释为什么它在运行时崩溃。这将需要一个完整的运行 CoreText 应用程序,而我没有。 #Martin R. Thx 获取更多背景信息。正如您所指的那样,“&”修复了编译器错误。我找到了一种处理运行时错误的方法,如下所示:我用 CGPointZero 加载 originsArray(CTFrameGetLines 报告的每一行一个。for _ in 0..ctLinesArray.count originsArray.append(CGPointZero) @eharo2:你是对的,必须已经有必要数量的元素。您可能可以将创建简化为 var originsArray = CGPoint[](count:ctLinesArray.count, repeatedValue: CGPointZero)

以上是关于Swift 中 CoreText CTFrameGetLineOrigins 的问题的主要内容,如果未能解决你的问题,请参考以下文章

自定义 uiscrollview 不滚动(使用 coretext)

CoreText

如何使用 Cocoa (Mac) 在 Swift 中创建 PDF

[NSFont fontWithName] 等效的 CoreText

iOS阅读器实践系列coretext纯文本排版基础

iPhone 上的 CoreText 和删除线