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

Xcode 15.3更新后NSTableView拖拽失效:NSKeyedUnarchiver适配问题

解决Xcode 15.3中NSKeyedUnarchiver新API导致拖拽数据解析失败的问题

问题出在新API的类校验逻辑上:拖拽过来的数组数据里包含具体的子元素类,而你之前只指定了NSArray.self,没有包含元素的实际类型,导致解包失败。

正确解决方案

在unarchivedObject(ofClasses:from:)中同时声明数组类和数组内元素的所有可能类:

  • 如果数组里是系统类(比如NSString、NSURL),把这些类也加入列表:
if let draggedArray = try? NSKeyedUnarchiver.unarchivedObject(ofClasses: [NSArray.self, NSString.self], from: data) as? [String] {
    // 处理解析后的拖拽数据
}
  • 如果数组里是自定义类,先确保自定义类遵循NSCoding,再把它加入类列表:
if let draggedItems = try? NSKeyedUnarchiver.unarchivedObject(ofClasses: [NSArray.self, CustomDraggableItem.self], from: data) as? [CustomDraggableItem] {
    // 处理自定义拖拽元素
}

为什么旧API能用?

废弃的unarchiveTopLevelObjectWithData(_:)没有强制类校验,会自动尝试解包所有符合NSCoding的对象;而新API要求显式声明所有可能出现的类,缺一个都会导致解包返回nil,进而让拖拽功能失效。

调试小技巧

如果不知道数组里的元素类型,先用旧API解析后打印类型:

if let rawObject = try? NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data) {
    print("顶层对象类型:\(type(of: rawObject))")
    if let array = rawObject as? [Any] {
        array.forEach { print("子元素类型:\(type(of: $0))") }
    }
}

把打印出来的所有子元素类都加入ofClasses列表即可。

内容的提问来源于stack exchange,提问作者Jon Brown

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 05:33:16