Why doesn't NSManagedObject instances hold a strong reference to their NSManagedObjectContext?

旧城冷巷雨未停 提交于 2019-11-29 02:08:25

It makes more sense for an NSManagedObjectContext to own its NSManagedObjects than the other way around.

Keep in mind that the context is like a draw pad with all its objects on it. If that context goes away, the objects are no longer valid. If the objects owned the context, then the context going away would do nothing to the objects and they still appeared to be valid. In other words: a context can exist without objects, objects can't exist without a context.

Of course, a hybrid model (where a context owns its objects and objects own their context) wouldn't work either, because then you would run into a retain cycle.

NSManagedObject instances are nearly useless without their context

They can be (though not necessarily), but remember that they do have a reference to their context! Presumably it's a weak reference, but a reference nonetheless. If that reference returns nil, the object is invalid. If you make sure your context stays around (which is what I did in my answer to the other question), you won't have any issues.

This is because you otherwise would get a retain cycle. The managed object context internally uses arrays and other containers which have references to the managed objects.

Possibly, this retain cycle cannot be "explicitly broken" that easily by the internal implementation of Core Data, so that this reference has to be weak.

Would it be dangerous to implement an NSManagedObject subclass that automatically holds a strong reference to its NSManagedObjectContext?

As others pointed out, this would be dangerous because you'd be creating a retain cycle.

A better practice would be to subscribe to the Notification

NSManagedObjectContextObjectsDidChange

Here you could update your objects whenever the context notifies you that it changed them.

Example:

- (void)addObservers
{
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(managedObjectContextChanged) name:NSManagedObjectContextObjectsDidChangeNotification object:_myManagedObjectContext];
}

- (void)managedObjectContextChanged
{
    [self fetchObjects];
}

Also, as Apple points out, be sure to pass the context you want to observe:

Several system frameworks use Core Data internally. If you register to receive these notifications from all contexts (by passing nil as the object parameter to a method such as addObserver(_:selector:name:object:)), then you may receive unexpected notifications that are difficult to handle.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!