我正在尝试制作一个与持久性框架无关的代码库。即我想要面向协议的程序设计,但是在CoreData上无法正常工作。
说我有一个协议:
public protocol BookItem {
var title: String { get }
var filename: String { get }
var createdAt: Date { get }
var content: BookItemContent? { get }
}
和另一个协议
public protocol BookItemContent {
var bookItem: BookItem { get }
var data: Data { get }
}
当我在CoreData中创建具体类型时,我可能会:
class CDBookItem: NSManagedObject, BookItem {
@NSManaged public var title: String?
@NSManaged public var filename: String?
@NSManaged public var createdAt: NSDate?
@NSManaged public var content: CDBookItemContent?
}
class CDBookItemContent: NSManagedObject, BookItemContent {
@NSManaged public var data: NSData?
@NSManaged public var bookItem: CDBookItem?
}
我在这里有3个问题:
1)现在,我有多个具有不同返回类型的属性。 (例如.content
属性)
如何最好地解决此问题?最糟糕和肮脏的方法是重命名所有Core-Data属性,然后包装它们以使其一致。
我可以看到的另一种方法是手动生成NSManagedObject子类,然后更改CoreData代码生成的风格,以消除可选项。尽管如此,我仍然剩下content: BookItemContent
和content: CDBookItemContent
,所以我不知道是否有一种优雅的方式来做我希望在这里做的事情。我希望我可以声明NSManagedObject子类符合其预期的协议类型,并且编译器可以解决这个问题。
2)核心数据代码生成器使用“ NSObject”类型,而不是现代等效物。 (即NSData而不是Data,NSDate而不是Date)。我可以只修改codegen文件以删除“ NS”并获得免费桥接吗?
3)是否知道CoreData总是在代码生成器中创建可选的对象属性,即使您不希望这样做也是如此?解决方案实际上是覆盖手动生成的文件吗?
答案 0 :(得分:0)
最后,我发现面向协议的编程并不完全符合承诺。我希望几乎可以用这种方式完成整个代码库。最后,解决方案是使NSManagedObject子类符合协议,方法是必须为协议的属性显式编写访问器,该访问器将一些属性包装在核心数据模型上。即return myManagedObject.contentObject as! BookItemContent