如何在Swift中定义核心数据关系?

时间:2014-06-22 10:19:24

标签: core-data swift ios8

在CoreData中,我定义了从NodeTag的无序多对多关系。我已经创建了一个像这样的Swift实体:

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)

然而,这失败并出现以下错误:

  

由于未捕获的异常终止应用&#39; NSInvalidArgumentException&#39;,原因:&#39;多对多关系的值不可接受的类型:property =&#34; tags&#34 ;;所需类型= NSSet ;给定type = _TtCSs22ContiguousArrayStorage000000000B3440D4;值=(       &#34;&lt; _TtC8MotorNav3Tag:0xb3437b0&gt; (entity:Tag; id:0xb343800; data:{...})&#34;   )&#39;

多对多关系的正确类型是什么?

4 个答案:

答案 0 :(得分:16)

为了能够在Swift中使用一对多关系,您需要将属性定义为:

class Node: NSManagedObject {
    @NSManaged var tags: NSSet
}

如果您尝试使用NSMutableSet,则更改将不会保存在CoreData中。当然,建议在Node中定义反向链接:

class Tag: NSManagedObject {
    @NSManaged var node: Node
}

但是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

答案 1 :(得分:12)

从Xcode 7和Swift 2.0开始,release note 17583057声明:

  

NSManaged属性可以与方法一起使用   属性,用于访问自动生成的Core Data   符合键值编码的兼容多种访问器。

@NSManaged func addTagsObject(tag: Tag)
@NSManaged func removeTagsObject(tag: Tag)
@NSManaged func addTags(tags: NSSet)
@NSManaged func removeTags(tags: NSSet)
  

这些可以在NSManagedObject子类中声明。 (17583057)

所以你只需声明以下方法,CoreData将负责其余的工作:

{{1}}

答案 2 :(得分:9)

实际上你可以定义:

@NSManaged var employees: Set<Employee>

直接使用insert的{​​{1}}和remove方法。

答案 3 :(得分:0)

建立@Kenenle的回答,如果你想要厚颜无耻,能够说出来

node.tags.append(tag)

可以将调用包装到self.mutableSetValueForKey:

class Node: NSManagedObject {

    var tags: NSMutableOrderedSet {
        return self.mutableOrderedSetValueForKey("tags")
    }
}