0

I'm implementing a UITableView as a first level view controller that contains 5 table cells. Hitting on any of these cells will present a second level view. At the top left of this level view, there is a "back" button to return to the first level view. At the second level view, swiping left or right will show adjacent views continuously that link to those adjacent table cells at the first level view.

After running, from first level view to second level view it's ok. But when hitting the "back" button, going back to first level view from second level view, the following is the issue I got.

An instance 0x7a8f130 of class UIScrollView was deallocated while key value observers were still registered with it. Observation info was leaked, and may even become mistakenly attached to some other object.
Set a breakpoint on NSKVODeallocateBreak to stop here in the debugger. 
Here's the current observation info: (
Context: 0x0, Property: 0x9149570>
)

I found

- (void)viewDidUnload
{
    [super viewDidUnload];
    [self.scrollView removeObserver:self forKeyPath:@"frame"];
    [self.scrollView removeFromSuperview];
    _scrollView = nil;
}

in the GDIInfinitePageScrollViewController.m that I'm using to implement an infinite scroll view controller. When I commented this out, the issue is still there.

when I set breakpoint NSKVODeallocateBreak, here is what I got

0x1170ae0:  pushl  %ebp

but I have no idea about what it means.

Does anyone know how to fix this issue?

Dave FN
  • 652
  • 1
  • 14
  • 29
S1U
  • 825
  • 2
  • 14
  • 26

2 Answers2

1

The reason you are getting that message is because the UIScrollView instance is being released before its observers are removed.

The method -(void) viewDidUnload is called when the view has already been released, so that call to remove the observer is too late. In addition, this has been deprecated with iOS 6, along with -(void) viewWillUnload.

As an alternative, try removing the observer when hitting the back button.

Dave FN
  • 652
  • 1
  • 14
  • 29
  • 2
    To be clear, the docs say, for both viewWillUnload and viewDidUnload: "**this method is never called.**" So it's not deprecated as in "not recommended" it's deprecated as in "will not work at all." – ipmcc Jul 08 '13 at 12:47
  • I tried `- (void)dealloc` by using same codes in `- (void)viewDidUnload` and at same time commented it out, like [this](http://i40.tinypic.com/o9hamr.png), then the issue never happen again. It looks resolved. Why? – S1U Jul 08 '13 at 20:45
  • As ipmcc mentioned, `-(void) viewDidUnload` is never called by the framework, so your code removing the observer was never executed. When you move from the second level back to the first level, the controller is released, which gets `-(void) dealloc` called. In here, you can still access your view and remove `self` as an observer. – Dave FN Jul 08 '13 at 20:52
  • Regarding "try removing the observer when hitting the back button", I'm not clear about this, because the back button is implemented in `- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath `in the first level view, while codes related to "remove observer blablabal..." are in `GDIInfinitePageScrollViewController.m`. So I've no idea about how to like these two. – S1U Jul 08 '13 at 20:55
  • So my try moving codes to `dealloc` is correct action to fix this issue? – S1U Jul 08 '13 at 20:58
  • Yes. As long as the observer is removed, you'll get rid of that error message. Objects usually stop observations in `dealloc`, so you'll be fine. – Dave FN Jul 08 '13 at 21:00
  • That's great! The last issue as of now is finally cleared! Amazing! Thank you Dave! – S1U Jul 08 '13 at 21:06
1

replacing - (void)viewDidUnload with - (void)viewWillDisappear worked for me

DTHENG
  • 188
  • 1
  • 7