My UIViewController has a UITableView. Each custom cell is given a model object with weak
association.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
List *list = self.lists[indexPath.row];
ListCoverTableViewCell *cell = (ListCoverTableViewCell *)[tableView dequeueReusableCellWithIdentifier:NormalCell forIndexPath:indexPath];
cell.list = list;
return cell;
}
Each cell then observes a property on the model object.
- (void)addProgressObserverToCell:(ListCoverTableViewCell *)cell
{
@try {
[cell.list.tasksManager addObserver:cell
forKeyPath:NSStringFromSelector(@selector(fractionCompleted))
options:0 context:nil];
} @catch (NSException *__unused exception) {}
}
addProgressObserverToCell:
is called from viewWillAppear (in case the user taps on a cell and comes back), and in tableView's willDisplayCell:
(for when the user scrolls).
A similar method removeProgressObserverFromCell
gets called in viewWillDisappear
(for when the user taps a cell and navigates away) and in tableView's didEndDisplayingCell
(for when the user scrolls).
- (void)removeProgressObserverFromCell:(ListCoverTableViewCell *)cell
{
@try {
[cell.list.tasksManager removeObserver:cell
forKeyPath:NSStringFromSelector(@selector(fractionCompleted))
context:nil];
} @catch (NSException *__unused exception) {}
}
So far, everything is balanced. I add observers in viewWillAppear/willDisplayCell, and remove them in viewWillDisappear/didEndDisplayingCell.
To be safe (and defensive), I updated my ViewController's dealloc method to also remove all observers. I simply loop through the tableView's visible cells and call removeProgressObserverFromCell:
.
By running this code in the dealloc, I'm finding the model objects stored within my UITableView's visibleCells
are never released. How is my defensive removal of observers causing my model object to be retained?