You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 11:30:09