使用对象归档时遭遇「users.archive不存在」错误,求排查解决
错误信息
2023-11-17 00:20:40.993562+0800 FriendCollege[80762:995113] [plugin] AddInstanceForFactory: No factory registered for id <CFUUID 0x600000270640> F8BB1C28-BAE8-11D6-9C31-00039315CD46
Error Domain=NSCocoaErrorDomain Code=260 "无法打开文件"users.archive",因为不存在该文件" UserInfo={NSFilePath=/Users/zhouzihao/Library/Developer/CoreSimulator/Devices/EB37A319-C800-4B6E-BF59-B9E3B50548FD/data/Containers/Data/Application/47DB7CC2-464B-4C84-AAFF-B881D5BC100D/Documents/users.archive, NSUnderlyingError=0x600000c7ad00 {Error Domain=NSPOSIXErrorDomain Code=2 "No such file or directory"}}
核心问题
代码中创建归档URL时,错误地将users.archive标记为目录:
return docDir.appendingPathComponent("users.archive", isDirectory: true)
isDirectory: true会让系统把目标路径识别为目录而非文件,导致读写操作无法找到对应的文件实体。
修复步骤
1. 修正归档URL
将URL创建代码中的isDirectory: true移除(默认值为false),或显式设为false:
let archiveURL : URL = { let docDirs = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask) let docDir = docDirs.first! return docDir.appendingPathComponent("users.archive") } ()
2. 优化初始化时的文件不存在处理
首次启动App时归档文件不存在是正常情况,可针对性处理避免冗余报错:
init() { do { let data = try Data(contentsOf: archiveURL) if let savedUsers = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data) as? [User] { UsersCollection = savedUsers } } catch CocoaError.fileNoSuchFile { // 文件不存在,初始化空数组 UsersCollection = [] } catch { print("归档读取失败:\(error)") } }
3. 替换强制类型转换
原代码中的as! [User]存在崩溃风险,改用as? [User]进行安全类型转换,如上述代码所示。
验证
修改完成后,首次调用saveUser()会正确创建users.archive文件,后续启动App即可正常读取归档内容。
内容的提问来源于stack exchange,提问作者zzhzzh

