Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
820 views
in Technique[技术] by (71.8m points)

core text - Issue with CoreText CTFrameGetLineOrigins in Swift

I have the following code working in Objective-C

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

But when ported to Swift, the compiler complains with a Cannot convert the expression′s ′Void′to type ′CMutablePointer<CGPoint> in the CTFrameGetLineOrigins line

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)

I had to use NSArray in the CGFrameGetLines function, and then convert to a Swift Array, and inspecting the ctLinesArray, shows that the CTLine objects are retrieved correctly

I tried using NSMutableArray for the originsArray, with the same result.

Any idea of what is missing?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You have to add the address-of operator & to pass the pointer to the start of the originsArray to the function:

CTFrameGetLineOrigins(ctFrame, range, &originsArray)

Reference: Interacting with C APIs in the "Using Swift with Cocoa and Objective-C" book:

C Mutable Pointers

When a function is declared as taking a CMutablePointer<Type> argument, it can accept any of the following:

  • ...
  • An in-out Type[] value, which is passed as a pointer to the start of the array, and lifetime-extended for the duration of the call.

And from Expressions in "The Swift Programming Language" book:

In addition to the standard library operators listed above, you use & immediately before the name of a variable that’s being passed as an in-out argument to a function call expression.

An addition (as @eharo2 already figured out), the originsArray must have room for the necessary number of elements, which can be achieved with

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...