如何在Swift中定义CoreData关系?

Bou*_*uke 12 core-data swift ios8

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

import CoreData
class Node : NSManagedObject {
    @NSManaged var tags : Array<Tag>
}
Run Code Online (Sandbox Code Playgroud)

现在我想添加一个Tag实例Node,如下所示:

var node = NSEntityDescription.insertNewObjectForEntityForName("Node", inManagedObjectContext: managedObjectContext) as Node
node.tags.append(tag)
Run Code Online (Sandbox Code Playgroud)

但是,这失败并出现以下错误:

由于未捕获的异常'NSInvalidArgumentException'而终止应用程序,原因:'to-many relationship的值不可接受的类型:property ="tags"; 期望的类型= NSSet ; 给定type = _TtCSs22ContiguousArrayStorage000000000B3440D4; value =("<_TtC8MotorNav3Tag:0xb3437b0>(entity:Tag; id:0xb343800; data:{...})").'

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

Kee*_*nle 17

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

class Node: NSManagedObject {
    @NSManaged var tags: NSSet
}
Run Code Online (Sandbox Code Playgroud)

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

class Tag: NSManagedObject {
    @NSManaged var node: Node
}
Run Code Online (Sandbox Code Playgroud)

但是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)
    }
}
Run Code Online (Sandbox Code Playgroud)

用法:

// somewhere before created/fetched node and tag entities
node.addTagObject(tag)
Run Code Online (Sandbox Code Playgroud)

重要提示:要使一切正常,您应该验证CoreData模型中实体的类名是否包含您的模块名称.例如MyProjectName.Node


Nyc*_*cen 12

从Xcode 7和Swift 2.0开始,发行说明 17583057指出:

NSManaged属性可以与方法和属性一起使用,以访问Core Data自动生成的符合键值编码的多个访问器.

@NSManaged var employees: NSSet

@NSManaged func addEmployeesObject(employee: Employee)
@NSManaged func removeEmployeesObject(employee: Employee)
@NSManaged func addEmployees(employees: NSSet)
@NSManaged func removeEmployees(employees: NSSet)
Run Code Online (Sandbox Code Playgroud)

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

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

@NSManaged func addTagsObject(tag: Tag)
@NSManaged func removeTagsObject(tag: Tag)
@NSManaged func addTags(tags: NSSet)
@NSManaged func removeTags(tags: NSSet)
Run Code Online (Sandbox Code Playgroud)


Fra*_*kel 10

实际上你可以定义:

@NSManaged var employees: Set<Employee>
Run Code Online (Sandbox Code Playgroud)

并直接使用insertremove方法Set.

  • 我实际上在同一时刻使用这种方法并且它正在工作. (2认同)