I am looking at a table view cell here and I find this code:
- (void)awakeFromNib {
[super awakeFromNib];
[self addObserver:self forKeyPath:@"model.isDownloading" options:NSKeyValueObservingOptionNew context:NULL];
[self addObserver:self forKeyPath:@"model.isCached" options:NSKeyValueObservingOptionNew context:NULL];
[self addObserver:self forKeyPath:@"model.isOutDated" options:NSKeyValueObservingOptionNew context:NULL];
[self addObserver:self forKeyPath:@"model.cacheUpdateDate" options:NSKeyValueObservingOptionNew context:NULL];
[self addObserver:self forKeyPath:@"model" options:NSKeyValueObservingOptionNew context:NULL];
}
The observers are removed in the dealloc
method. model
is a weak
property, receiving a managed object (core-data).
I receive spurious crashes, telling me, that the managed object is deleted, but still has observers registered.
Why the error happens is pretty clear to me: The object is removed somewhere in the background, but still linked into the tableview's cell. Since dealloc
on the cell is basically never called during lifetime of the application, the observers are never really removed. Since the reference to the core-data object is weak
, it will deallocate silently in the background - at least try to. This fails, because the model is still observed.
I have some questions:
- If a path like "model.isDownloading" is observed, then the observer is registered in the
model
object, not in the setter inself
, is that correct? - Is objC smart enough to handle the observer change if
model
is reassigned (self.model = newThing
requires, thatremoveObserver
is called onmodel
before assigningnewThing
, and observers need to be registered onnewThing
after that). - Since the crash happens on dealloc of the managed object, I think a simple solution would be, to make
model
strong instead ofweak
, and of course make sure, that it is properly set tonil
inprepareForReuse:
. Does this have side effects, that I have not realized?
The error message is:
class xxx was deallocated while key value observers were still registered with it