简体   繁体   中英

iOS (Swift): Core data fetching with relationships

If I have a Person entity and a Book entity where a Person can have many 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
    }

}

In some UIViewController , I then add a few Book s to a 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)

and then a couple of Book s to another 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)

I then reload my app and use a fetch request to obtain all the people (ie alex and john ) in a table view. I then click on alex , which takes me to another view controller, which has an instance of Person that I assign as alex so that I can view the books associated to this instance.

Question Are the Book s all loaded into memory even if I have 1000s? Or do I need to perform another fetch to get the Book s belonging to alex if I want to display them all? I just want a bit of clarity on what is happening with relationships between two entities as it's slightly confused me recently.

Thanks for any help.

CoreData uses a proxy object model. When you execute a fetch request it transparently creates all directly accessible objects, as proxies. Since they're proxies and not the full object, they are not actually loaded from the data base at creation time, rather they will be loaded from the database when needed (when properties are actually referenced) Likewise, they can be unloaded at any time if they're unmodified and unused.

In this case, that means that your fetch request will create unloaded proxies for each Person . When you display the persons name in the first table view, the data for that Person will be loaded (and cached) in the proxy object. At that time, proxies for each Book referenced by the person will be created as an empty proxy object. When you subsequently select the book and display the details of the book, the actual Book data will be fetched (cached) from the database.

Note: all this is very dependent on the actual datastore in use and is only true of stores, such as sqlite, that allow partial loading. If using an XML or plist store the entire object graph is instantiated and loaded with no empty proxies.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM