You should probably have a state property to keep track of whether you added your observer or not. It's possible that you might not see a viewWillDisappear
when your activity view indicator controller is presented, even though you might see viewWillAppear
be called again when you return. Thus, when you dismiss your view controller, you'd added the observer twice, but are only removing it once.
Put in some NSLog
statements and I bet you'll find that your calls to viewWillDisappear
and viewWillAppear
are not balanced (through no fault of your own). As a result, I bet you're adding the observer more times than you're removing it.
By adding a state property, observingContentOffset
, you can remedy this:
@property (nonatomic) BOOL observingContentOffset;
You can then have your code that adds and removes the observer check this property:
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated]; // don't forget to call super
if (!self.observingContentOffset) {
[self.tableView addObserver:self forKeyPath:@"contentOffset" options:NSKeyValueObservingOptionNew context:NULL];
self.observingContentOffset = YES;
}
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated]; // don't forget to call super
if (self.observingContentOffset) {
[self.tableView removeObserver:self forKeyPath:@"contentOffset"];
self.observingContentOffset = NO;
}
}
While the above should remedy your issue, I would take this a step further and suggest you consider retiring this KVO code entirely. Since the tableview is actually a subclass of a scroll view, when you set the table view's delegate, you're also specifying the delegate for the underlying scrollview. Thus, having specified your table view's delegate, it will also serve as the scroll view delegate and you can simply implement the relevant UIScrollViewDelegate
method(s). If you need to identify every scroll event, that's probably a more robust technique than KVO (and it coincidentally eliminates your original problem, too). And if you only need to identify when cells are removed from the view, iOS 6 provides some relevant high-level UITableViewDelegate
methods that make it even easier.