Search code examples
ioscore-dataautomatic-ref-counting

Why is there a Weak References Between Managed Objects and the Context?


When i was learning how to use child contexts :

 let childContext =
 NSManagedObjectContext(
concurrencyType: .mainQueueConcurrencyType)
 childContext.parent = coreDataStack.mainContext

let childEntry =
childContext.object(with: surfJournalEntry.objectID)
as? JournalEntry
 // 3
detailViewController.journalEntry = childEntry
detailViewController.context = childContext
detailViewController.delegate = self

Author made some remark about passing both managed object and the managed object context to the detailViewController:

Note: You might be wondering why you need to pass both the managed object and the managed object context to the detailViewController, since managed objects already have a context variable. This is because managed objects only have a weak reference to the context. If you don’t pass the context, ARC will remove the context from memory (since nothing else is retaining it) and the app will not behave as you expect.

Well, ok, so then a read some official doc:

This means that in general you cannot rely on a context to ensure the longevity of a managed object instance, and you cannot rely on the existence of a managed object to ensure the longevity of a context. Put another way, just because you fetched an object doesn’t mean it will stay around.

But yet, i don't get what is true intention of making weak references between managed objects and the context? What is the goal do they pursue?


Solution

  • Managed object contexts usually use weak references to fetched objects to avoid the potential for excessive memory use. If it used strong references, and you did one or more fetches that found a large number of results, all of them would remain in memory for as long as the context existed. In many apps that would mean they'd never go away, because the context exists until the app exits. That could cause the app to use a lot of memory for objects it wasn't using anymore. Weak references mean that the managed objects are deallocated as soon as the app stops using them.

    But you might want strong references in some cases, so there's a boolean property called retainsRegisteredObjects that makes the context use strong references instead. Use it if you like, but be careful of memory use.

    Managed objects don't keep strong references to their contexts to avoid reference cycles. If they were strong references and you set retainsRegisteredObjects to true, you'd get a reference cycle. Each object would hold a strong reference to the other, so neither could be released from memory unless you set one of the references to nil.