如果我有一个Person
实体和一个Book
实体,其中Person
可以有很多Book
。
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
中,我随后在Person
中添加了几个Book
:
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)
然后,我重新加载我的应用程序并使用获取请求来获取所有人(即 表视图中的alex
和john
(。然后,我单击"alex
",这会将我带到另一个视图控制器,该控制器具有我指定为alex
的Person
实例,以便我可以查看与此实例关联的书籍。
问题即使我有 1000 个,Book
是否全部加载到内存中?或者,如果我想全部显示它们,我是否需要执行另一次提取才能获取属于alex
的Book
?我只是想澄清一下两个实体之间的关系发生了什么,因为它最近让我有点困惑。
感谢您的任何帮助。
CoreData
使用代理对象模型。 当您执行获取请求时,它会透明地创建所有可直接访问的对象作为代理。 由于它们是代理而不是完整对象,因此它们实际上不会在创建时从数据库加载,而是在需要时从数据库加载它们(当实际引用属性时(同样,如果它们未经修改和未使用,则可以随时卸载它们。
在这种情况下,这意味着您的获取请求将为每个Person
创建卸载的代理。 在第一个表视图中显示人员姓名时,该人员的数据将加载(并缓存(在代理对象中。 届时,该人引用的每本书的代理将创建为空代理对象。 当您随后选择书籍并显示书籍的详细信息时,将从数据库中获取(缓存(实际的书籍数据。
注意:所有这些都非常依赖于正在使用的实际数据存储,并且仅适用于允许部分加载的存储,例如 sqlite。 如果使用 XML 或 plist 存储,则会实例化整个对象图并加载,没有空代理。