如何在 Swift 2.0 中创建 CTRunDelegate

How to create CTRunDelegate in Swift 2.0

我正在使用 CoreText 来处理 NSTextAttachment。 CoreText 需要一个 CTRunDelegate 来布局附件。但是当运行下面的代码时我得到了错误。

class RunDelegate: NSObject {
    let image: UIImage
    let font: UIFont

    init(image: UIImage, font: UIFont) {
        self.image = image
        self.font = font
    }
}

private func generateRunDelegate(attachment: NSTextAttachment, font: UIFont) -> CTRunDelegateRef {
    var d = RunDelegate(image: attachment.image!, font: font)
    var cbs = CTRunDelegateCallbacks(version: kCTRunDelegateCurrentVersion, dealloc: { (p) -> Void in

        }, getAscent: { (p) -> CGFloat in
            let d = UnsafeMutablePointer<RunDelegate>(p).memory
            return d.image.size.height + d.font.descender // Error here, EXC_BAD_ACCESS(code = 1)
        }, getDescent: { (p) -> CGFloat in
            let d = UnsafeMutablePointer<RunDelegate>(p).memory
            return -d.font.descender
        }) { (p) -> CGFloat in
            let d = UnsafeMutablePointer<RunDelegate>(p).memory
            return d.image.size.width
    }
    return CTRunDelegateCreate(&cbs, &d)!
}

有人可以帮忙吗?谢谢!

请尝试此代码。

class RunDelegate: NSObject {
    let image: UIImage
    let font: UIFont

    class func object(pointer: UnsafeMutablePointer<Void>) -> RunDelegate {
        return Unmanaged<RunDelegate>.fromOpaque(COpaquePointer(pointer)).takeRetainedValue()
    }

    init(image: UIImage, font: UIFont) {
        self.image = image
        self.font = font
    }
}

private func generateRunDelegate(attachment: NSTextAttachment, font: UIFont) -> CTRunDelegateRef {
    var d = RunDelegate(image: attachment.image!, font: font)
    var cbs = CTRunDelegateCallbacks(version: kCTRunDelegateCurrentVersion,
           dealloc: { (p) -> Void in

        }, getAscent: { (p) -> CGFloat in
            let d = RunDelegate.object(pointer: p)
            return d.image.size.height + d.font.descender
        }, getDescent: { (p) -> CGFloat in
            let d = RunDelegate.object(pointer: p)
            return -d.font.descender
        }) { (p) -> CGFloat in
            let d = RunDelegate.object(pointer: p)
            return d.image.size.width
    }
    return CTRunDelegateCreate(&cbs, d)!
}

我以为是UnsafePointer没有正确生成。