我有一个短链的核心数据实体,具有一对多关系:
- 用户有零到多条推文
- 推文具有零到多个 MediaObject(例如推文中附加的照片)
- MediaObject 具有零到多个变体(例如视频的不同 mp4 编码)
关系“对多”端的每个实体也有一个备份到所属实体的关系;即“推文”也具有一对一的“用户”关系,并且媒体对象也具有“推文”关系。
多对一关系似乎适用于一层深度(用户->推文),但不适用于更深层次(推文->媒体或媒体->变体)
当我尝试构建时,我得到:
/Users/USERNAME/Library/Developer/Xcode/DerivedData/PROJECT_NAME-apwnbsxvzneyrubfissqvdylmkys/Build/Intermediates/PROJECT_NAME.build/Debug-iphonesimulator/PROJECT_NAME.build/DerivedSources/CoreDataGenerate/PROJECT_NAME/TweetMediaPhoto+CoreDataClass.swift :14:58:初始化程序要求“init(entity:insertInto:)”只能由非最终类“TweetMediaPhoto”中的“必需”初始化程序来满足
我以为这会由 XCode 为我生成,当我点击相关文件时,会出现一条警告,要求不要直接编辑它:
//
// TweetMediaPhoto+CoreDataClass.swift
//
//
// Created by David Godfrey on 22/03/2017.
//
// This file was automatically generated and should not be edited.
//
import Foundation
import CoreData
@objc(TweetMediaPhoto)
public class TweetMediaPhoto: TweetMedia {
}
(虽然 TweetMediaPhoto 继承自 TweetMedia 并且不直接继承自 NSManagedObject,但我尝试重构实体以复制 TweetMedia 中的属性并使层次结构平坦;这除了更新签名以读取 : NSManagedObject
在生成的代码中,同时仍然显示构建错误)
事实上,Swift 文档直接指出 "You are discouraged from overriding this method"即使我要创建自己的类。
造成此问题的原因是什么?如何修复此构建错误?
最佳答案
事实证明,这是与自定义协议(protocol) KnownCoreDataEntity
相关的一些问题。
- 该协议(protocol)要求
NSManagedObject
初始化器init(entity:insertInto:)
可用,并且许多实体实现了该协议(protocol)。我相信由于 CoreData 与 ObjC 桥接的事实,Swift 编译器对此不满意,因为它提出了技术上可能无法满足的要求。删除对 init 的明确要求,并使用扩展名 KnownCoreDataEntity 来扩展协议(protocol),其中 Self: NSManagedObject {
允许访问初始化程序。 - 出现的另一个错误是
声明不能同时是“final”和“dynamic”
- 这是由相同的协议(protocol)引起的,需要static var EntityName: String { get }
- 将静态 EntityName 属性更改为let
和/或使用@nonobjc
标记该属性也解决了此问题。
我在创建实体时使用此协议(protocol)来减少样板文件。 create(withGivenContext:NSManagedObjectContext?)
方法和 loadOrCreate(withId:Int64,andGivenContext:NSManagedObjectContext?)
方法将处理检索上下文(如果未提供),并处理检查对象是否存在;被调用者通常不关心是否需要创建实体,它通常只需要一个可以开始操作的引用。
关于ios - 使用 codegen 的核心数据实体导致 "initializer required ' init(entity :insertInto: )' " error,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42960380/