升级Xcode 13后归档项目出现Core Data相关编译错误该如何解决?
问题原因
- Xcode 13及以上版本调整了Core Data自动生成代码的逻辑,原本
NSManagedObject子类自动生成的fetchRequest()静态方法返回值类型为NSFetchRequest<NSFetchRequestResult>,新版改为返回NSFetchRequest<Self>(泛型参数为当前子类类型)。 - Debug模式下默认关闭严格类型校验,Swift编译器会默认做隐式类型转换,匹配协议要求的返回类型,因此不会报错;归档时默认使用Release配置,开启严格类型校验,隐式转换失效,因此会抛出协议不匹配、找不到对应方法的错误。
修复方案
方案1:手动补充匹配协议要求的fetchRequest实现
在所有遵守ManagedObjectProtocol的NSManagedObject子类扩展中,手动添加返回类型符合协议要求的fetchRequest()实现,避免依赖系统自动生成的方法:
extension AppEntity: ManagedObjectProtocol { typealias Entity = App static var identifierKey: String { return "articleId" } // 新增以下方法 static func fetchRequest() -> NSFetchRequest<NSFetchRequestResult> { return NSFetchRequest<NSFetchRequestResult>(entityName: "AppEntity") } func toEntity() -> Entity? { return nil } }
方案2:修改通用查询方法,不依赖自动生成的fetchRequest
将两个辅助方法中调用自动生成fetchRequest()的逻辑替换为手动构造请求的实现,彻底规避类型匹配问题:
修复get方法:
将两处let fetchRequest = Entity.fetchRequest()替换为:
let fetchRequest = NSFetchRequest<Entity>(entityName: String(describing: Entity.self))
修复count方法:
将let fetchRequest = entity.fetchRequest()替换为:
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: String(describing: entity))
可选方案:调整协议定义适配新的返回类型
修改ManagedObjectProtocol中fetchRequest()的返回类型定义,增加关联类型适配新版自动生成的方法返回值:
protocol ManagedObjectProtocol { associatedtype Entity // 新增关联类型 associatedtype FetchResult: NSFetchRequestResult = Self static var identifierKey: String { get } // 修改返回类型 static func fetchRequest() -> NSFetchRequest<FetchResult> func toEntity() -> Entity? }
内容的提问来源于stack exchange,提问作者Libor Zapletal
相关产品推荐
相关产品推荐

