Swift遍历已加载OpenType字体FourCharCode表标签时崩溃问题排查
问题分析与解决方案
崩溃的核心原因是**CFArrayGetValueAtIndex返回的指针并非指向FourCharCode的原始内存地址**——CTFontCopyAvailableTables返回的CFArray中直接存储的是FourCharCode类型的值,而非指针。你错误地将其当作UnsafeRawPointer调用load方法,相当于在一个无效的整数地址上尝试读取数据,必然触发内存访问崩溃。
修正后的代码(两种写法)
写法一:Swift数组桥接(推荐)
直接将CFArray桥接为Swift数组,避免手动处理指针:
guard let allTableTags = CTFontCopyAvailableTables(theFont!, CTFontTableOptions(rawValue: 0)) as? [FourCharCode] else { return } for tag in allTableTags { let str = Utility.tagToString(tag) debugPrint("tag: \(str)") }
写法二:C风格API修正
如果需要保留CFArray的原生调用方式,需正确获取指针指向的元素值:
allTableTags = CTFontCopyAvailableTables(theFont!, CTFontTableOptions(rawValue: 0)) guard let allTableTags = allTableTags else { return } let numTags = CFArrayGetCount(allTableTags) for i in 0..<numTags { // 明确指针指向的类型,直接获取元素值 let tag = CFArrayGetValueAtIndex(allTableTags, i).assumingMemoryBound(to: FourCharCode.self).pointee let str = Utility.tagToString(tag) debugPrint("tag: \(str)") }
关键说明
- CFArray在Swift中支持自动桥接为对应元素类型的Swift数组,这是最安全简洁的处理方式。
- 若使用C风格API,
CFArrayGetValueAtIndex返回的UnsafeRawPointer是数组元素的地址,需通过assumingMemoryBound(to:)指定元素类型后,用pointee获取实际值,而非调用load方法——load适用于从指针指向的内存读取数据,而此处指针本身就是元素的直接地址。
内容的提问来源于stack exchange,提问作者jsbox
相关产品推荐
相关产品推荐

