iOS(Swift):使用关系

时间:2018-06-01 15:24:31

标签: ios swift core-data nsfetchedresultscontroller

如果我有一个Person实体和一个Book实体,Person可以有多个Book s。

final class Person: NSManagedObject {
    @NSManaged public fileprivate(set) var name: String
    @NSManaged public fileprivate(set) var books: Set<Book>
}

final class Book: NSManagedObject {

    @NSManaged public fileprivate(set) var name: String
    @NSManaged public fileprivate(set) var person: Person

    static func add(bookNamed name: String, to person: Person) {
        guard let context = person.managedObjectContext else { fatalError("Can not obtain managed object Context") }
        let book = NSEntityDescription.insertNewObject(forEntityName: "Book", into: context) as Book
        book.name = name
        book.person = person
    }

}

在某些UIViewController中,我向Book添加了一些Person

let alex = NSEntityDescription.insertNewObjectForEntityForName("Person", inManagedObjectContext: context) as Person
Alex.name = "Alex"
Book.add("first book", to: alex)
Book.add("second book", to: alex)
Book.add("third book", to: alex)

然后将几个Book添加到另一个Person

let john = NSEntityDescription.insertNewObjectForEntityForName("Person", inManagedObjectContext: context) as Person
john.name = "John"
Book.add("another first book", to: john)
Book.add("another second book", to: john)

然后我重新加载我的应用并使用获取请求在表格视图中获取所有人(即alexjohn)。然后我点击alex,它将我转到另一个视图控制器,该控制器的Person实例我指定为alex,以便我可以查看与此实例关联的书籍。< / p>

问题即使我有1000个,Book是否全部加载到内存中?或者我是否需要执行另一次提取以获取属于Book的{​​{1}},如果我想全部显示它们?我只想稍微澄清一下两个实体之间的关系,因为它最近让我感到困惑。

感谢您的帮助。

1 个答案:

答案 0 :(得分:2)

CoreData使用代理对象模型。执行获取请求时,它会透明地创建所有可直接访问的对象,作为代理。由于它们是代理而不是完整对象,它们实际上并不是在创建时从数据库加载,而是在需要时(当实际引用属性时)从数据库加载它们。同样,它们可以随时卸载如果他们没有修改和未使用。

在这种情况下,这意味着您的获取请求将为每个Person创建卸载的代理。在第一个表视图中显示人员名称时,将在代理对象中加载(和缓存)该人员的数据。那时,人员引用的每本书的代理将被创建为空代理对象。当您随后选择书籍并显示书籍的详细信息时,将从数据库中提取(缓存)实际的书籍数据。

注意:所有这些都非常依赖于正在使用的实际数据存储区,并且仅适用于允许部分加载的存储(例如sqlite)。如果使用XML或plist存储,则实例化整个对象图并加载没有空代理。