在CoreData中,我定义了从Node到无序的多对多关系Tag。我创建了一个这样的Swift实体:
Node
Tag
import CoreData class Node : NSManagedObject { @NSManaged var tags : Array<Tag> }
现在,我要向Tag的实例添加Node,如下所示:
var node = NSEntityDescription.insertNewObjectForEntityForName("Node", inManagedObjectContext: managedObjectContext) as Node node.tags.append(tag)
但是,此操作失败并显示以下错误:
由于未捕获的异常“ NSInvalidArgumentException”而终止应用程序,原因:“一对多关系的值的不可接受类型:property =“ tags”; 所需的类型= NSSet ; 给定类型= _TtCSs22ContiguousArrayStorage000000000B3440D4; 值=(“ <_TtC8MotorNav3Tag:0xb3437b0>(实体:Tag; id:0xb343800; data:{…})”)。
一对多关系的正确类型是什么?
为了能够在Swift中处理一对多关系,您需要将property定义为:
class Node: NSManagedObject { @NSManaged var tags: NSSet }
如果您尝试使用NSMutableSet更改,则不会保存在CoreData中。当然,建议在以下位置定义反向链接Node:
NSMutableSet
class Tag: NSManagedObject { @NSManaged var node: Node }
但是Swift仍然无法在运行时生成动态访问器,因此我们需要手动定义它们。在类中定义它们extension并放入Entity+CoreData.swift文件中非常方便。波纹管是Node+CoreData.swift文件的内容:
extension
Entity+CoreData.swift
Node+CoreData.swift
extension Node { func addTagObject(value:Tag) { var items = self.mutableSetValueForKey("tags"); items.addObject(value) } func removeTagObject(value:Tag) { var items = self.mutableSetValueForKey("tags"); items.removeObject(value) } }
用法:
// somewhere before created/fetched node and tag entities node.addTagObject(tag)
重要说明: 要使其全部正常工作,您应该验证CoreData模型中实体的类名称包括模块名称。例如MyProjectName.Node
MyProjectName.Node