如何在Swift中定义CoreData关系? [英] How to define CoreData relationship in Swift?

查看:150
本文介绍了如何在Swift中定义CoreData关系?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  import CoreData 
class Node:NSManagedObject {
@ NSManaged var tags:Array< Tag>
}

现在我要添加一个标签 Node 的实例,如下所示:

  var node = NSEntityDescription.insertNewObjectForEntityForName(Node,inManagedObjectContext:managedObjectContext)as Node 
node.tags.append(tag)

但是,此操作失败并显示以下错误:


由于未捕获异常NSInvalidArgumentException :'对于多对多关系的不可接受的值类型:property =tags;所需类型= NSSet ;给定类型= _TtCSs22ContiguousArrayStorage000000000B3440D4; value =(
< _TtC8MotorNav3Tag:0xb3437b0>(entity:Tag; id:0xb343800; data:{...})
)。




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

解决方案

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

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

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

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

但是仍然Swift不能在运行时生成动态访问器,所以我们需要手动定义它们。在类 extension 中定义它们并放在 Entity + CoreData.swift 文件中非常方便。 Bellow是 Node + CoreData.swift 文件的内容:

  {
func addTagObject(value:Tag){
var items = self.mutableSetValueForKey(tags);
items.addObject(value)
}

func removeTagObject(value:Tag){
var items = self.mutableSetValueForKey(tags);
items.removeObject(value)
}
}



  //在创建/获取节点和标签实体之前的某处
node.addTagObject(tag)
要使其一切正常,您应该验证CoreData中的实体的类名称。 模型包括您的模块名称。例如。 MyProjectName.Node


In CoreData, I have defined an unordered to-many relationship from Node to Tag. I've created an Swift entity like this:

import CoreData
class Node : NSManagedObject {
    @NSManaged var tags : Array<Tag>
}

Now I want to add a Tag to an instance of Node, like this:

var node = NSEntityDescription.insertNewObjectForEntityForName("Node", inManagedObjectContext: managedObjectContext) as Node
node.tags.append(tag)

However, this fails with the following error:

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Unacceptable type of value for to-many relationship: property = "tags"; desired type = NSSet; given type = _TtCSs22ContiguousArrayStorage000000000B3440D4; value = ( "<_TtC8MotorNav3Tag: 0xb3437b0> (entity: Tag; id: 0xb343800 ; data: {...})" ).'

What is the correct type for to-many relationships?

解决方案

To be able to work with one-to-many relationship in Swift you need to define property as:

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

If you try to use NSMutableSet changes will not be saved in CoreData. And of course it is recommended to define reverse link in Node:

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

But still Swift cannot generate dynamic accessors in runtime, so we need to define them manually. It is very convenient to define them in class extension and put in Entity+CoreData.swift file. Bellow is content of Node+CoreData.swift file:

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)
    }
}

Usage:

// somewhere before created/fetched node and tag entities
node.addTagObject(tag)

Important: To make it all work you should verify that class names of entities in you CoreData model includes your module name. E.g. MyProjectName.Node

这篇关于如何在Swift中定义CoreData关系?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆