如何在Swift中分配CoreData多对多关系?

tad*_*asz 24 cocoa-touch core-data ios swift

我有一个NSManagedObject类

class Disease: NSManagedObject {
    @NSManaged var diseaseId: String
    @NSManaged var diseaseName: String
    @NSManaged var dogBreed: NSSet
}
Run Code Online (Sandbox Code Playgroud)

如何为dogBreed添加新关系?如果我将var类型更改为NSMutableSet,则更改不会保存到数据库.有任何想法吗?

Nyc*_*cen 21

从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 addDogBreedsObject(dogBreed: DogBreed)
@NSManaged func removeDogBreedsObject(dogBreed: DogBreed)
@NSManaged func addDogBreeds(dogBreeds: NSSet)
@NSManaged func removeDogBreeds(dogBreeds: NSSet)
Run Code Online (Sandbox Code Playgroud)

  • @Emptyless这与Swift没什么关系.这些方法是由CoreData生成的,它是实际处理它的NSManaged类.上面的答案只是解释了使用Swift这样做的正确方法.它与在UIViewControllers中声明IBOutlets非常相似,并且您询问Swift如何知道如何将其链接到Storyboard(它也不是Swift,它是UIKit) (2认同)
  • 你说它们是生成的但也许我错过了什么?我添加了两个从俱乐部到成员的关系,反之亦然.我已经将它们设置为许多关系并且反过来指向它们自己.我生成NSManagedSubclasses时仍然没有方法.只有NSSet,从而导致我的问题如何将这些方法指向NSSet.提前致谢! (2认同)
  • @Emptyless CoreData一方面生成了底层的Key-Value方法,另一方面依赖于这些方法的Swift方法.当您生成NSManagedSubclasses时,XCode生成一些(但不是全部)所述Swift方法以节省您一些时间.您必须手动编写它不会为您生成的那些,即使已经存在基础KV方法. (2认同)

Kee*_*nle 18

由于严格的类型系统,Swift无法生成动态运行时访问器.您可以创建Disease类的扩展并手动添加遗漏方法,这里是代码:

extension Disease {
    func addDogBreedObject(value:DogBreed) {
        var items = self.mutableSetValueForKey("dogBreed");
        items.addObject(value)
    }

    func removeDogBreedObject(value:DogBreed) {
        var items = self.mutableSetValueForKey("dogBreed");
        items.removeObject(value)
    }
}
Run Code Online (Sandbox Code Playgroud)

备注:

我建议你为扩展创建单独的文件Disease+CoreData.swift,这有助于在重新生成CoreData模型时防止代码覆盖.

在其中一个托管对象中创建关系就足够了,第二个将使用后向引用进行更新.(与Objective-C相同)

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

答案的灵感来源:在Swift中设置NSManagedObject关系


naz*_*naz 10

如果您正在寻找一种简单的方法,请使用它.

import CoreData
extension NSManagedObject {
    func addObject(value: NSManagedObject, forKey: String) {
        var items = self.mutableSetValueForKey(forKey);
        items.addObject(value)
    }
}
Run Code Online (Sandbox Code Playgroud)

实施:

department.addObject(section, forKey: "employees")
Run Code Online (Sandbox Code Playgroud)

而不是在需要它的每个NSManageObject类上编写相同的方法.


Fra*_*kel 5

其实你可以这样写:

@NSManaged var dogBreed: Set<DogBreed>
Run Code Online (Sandbox Code Playgroud)

并直接使用的insertremove方法Set