Core data 如何在Swift中定义CoreData关系?
在CoreData中,我定义了从Core data 如何在Swift中定义CoreData关系?,core-data,swift,ios8,Core Data,Swift,Ios8,在CoreData中,我定义了从节点到标记的无序到多的关系。我创建了这样一个Swift实体: import CoreData class Node : NSManagedObject { @NSManaged var tags : Array<Tag> } var node = NSEntityDescription.insertNewObjectForEntityForName("Node", inManagedObjectContext: managedObjectCo
节点到标记的无序到多的关系。我创建了这样一个Swift实体:
import CoreData
class Node : NSManagedObject {
@NSManaged var tags : Array<Tag>
}
var node = NSEntityDescription.insertNewObjectForEntityForName("Node", inManagedObjectContext: managedObjectContext) as Node
node.tags.append(tag)
但是,此操作失败,并出现以下错误:
由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“to-many关系的值类型不可接受:property=“tags”;所需类型=NSSet;给定类型=_TtCSs22ContiguousArrayStorage000000000B3440D4;值=(
“(实体:标记;id:0xb343800;数据:{…})”
).'
多对多关系的正确类型是什么?要在Swift中处理一对多关系,您需要将属性定义为:
class Node: NSManagedObject {
@NSManaged var tags: NSSet
}
如果尝试使用NSMutableSet
更改将不会保存在CoreData中。当然,建议在节点中定义反向链接:
class Tag: NSManagedObject {
@NSManaged var node: Node
}
但Swift仍然无法在运行时生成动态访问器,因此我们需要手动定义它们。在classextension
中定义它们并将其放入Entity+CoreData.swift
文件中非常方便。下面是节点+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
以@Keenle的答案为基础,如果你想变得厚颜无耻、简洁,并且能够说
node.tags.append(tag)
可以将调用包装为self.mutableSetValueForKey:
class Node: NSManagedObject {
var tags: NSMutableOrderedSet {
return self.mutableOrderedSetValueForKey("tags")
}
}
截至Xcode 7和Swift 2.0,17583057声明:
NSManaged属性既可以与方法一起使用,也可以与
属性,用于访问自动生成的核心数据
键值编码兼容许多访问器
这些可以在NSManagedObject子类中声明。(17583057)
因此,您只需声明以下方法,CoreData将处理其余方法:
@NSManaged func addTagsObject(tag: Tag)
@NSManaged func removeTagsObject(tag: Tag)
@NSManaged func addTags(tags: NSSet)
@NSManaged func removeTags(tags: NSSet)
实际上,您可以定义:
@NSManaged var employees: Set<Employee>
@NSManaged var employees:Set
并直接使用集合
的插入
和删除
方法。NSSet在Swift中不可用?您在哪里找到的?错误消息还表明关系是有序的,而不是无序的。@BryanChen啊,是的,您的评论使我意识到NSSet可以通过Foundation
@MartinR获得。我复制了错误消息,它仍然被定义为有序集。@bouke:错误消息仍然提到".. “ordered to many relationship”的值。能否请您将实际的错误消息复制/粘贴到问题中,以避免将来读者的混淆?嘿,Keenie,当我使用您的扩展名时,我得到错误:“'NSSet'没有名为'addTagObject'的成员”“
。你知道我可能做错了什么吗?@Pirijan,你必须在tags:NSSet属性上调用addTagObject方法,而你应该在具有tags属性的对象上调用它。谢谢Keenle,我想不出来,所以我在这里发布了一个更全面的问题:谢谢,尽管后来发布了,你的答案更完整,我为此奖励你:)。这对我来说不起作用。在对to-many关系的父级调用remove函数后,尝试保存失败,因为子级仍然存在,但其与父级的所需关系为零。您是否检查了此操作是否有效?如果你在修改了员工设置后保存了模型,那么修改是否会被保存呢?我实际上在同一时刻使用了这种方法,它正在工作。很有趣!我不知道这是可能的。苹果真的应该澄清核心数据/Swift的使用情况,我认为……在一些常见的情况下,设置应该是可选的吗?还是最好在您的示例中定义它?这非常有帮助,谢谢。我发现很多核心数据信息都是以Objective-C约定表达的,因此,我们非常欣赏快速具体的解释。
@NSManaged var employees: Set<Employee>