Ryan Pfeffer
Ryan Pfeffer

Reputation: 895

Zombie Objects From Views instantiated from Interface Builder

I've got a crash that happens at a critical point in our application. However, the crash appears to be coming from an overreleased UIView object (more specifically the header view of a UITableView, which in this case is a UISearch bar). The odd thing about this is that that was instantiated from a nib file. Here's the crash...

I've setup my nib file to match exactly what Apple has in one of its sample projects.

enter image description here

I've also taken the time to analyze this with NSZombieEnabled and using Instruments. However I still can't make heads or tails as to why this is happening. Here's the Pairing of Retain/Releases....

enter image description here

And the stack trace exposing when the UIView object is created.

enter image description here

The common example of this type of error is an NSError object that is created and assigned to an out parameter within an autorelease block. However, I would not expect to see the same problem with a UIView. Nor do I see an autorelease block anywhere in my code (save the one on the main run loop). Any thoughts on how I might solve this problem?

Upvotes: 7

Views: 280

Answers (2)

Nils Ziehn
Nils Ziehn

Reputation: 4331

The Problem is, that listening for notifications or adding an KVO observer does not change the retaincount of the observing object. And there seems to be a notification fired right after the deallocation of you're view/viewcontroller/object.

You could changed the - (void)dealloc Method to remove the notification/KVO observer from your view/viewcontroller

Notifications:

-(void) dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self];
    //if you are not using ARC you also have to write
    //[super dealloc];
}

For KVO use Method with your keypath(s)

- (void)removeObserver:(NSObject *)anObserver forKeyPath:(NSString *)keyPath

Cheers, Nils

Upvotes: 1

mbpro
mbpro

Reputation: 2490

I don't have a lot of information, but let me share some thoughts:

  • KVO is a bad pattern for receiving data asynchronously, since as @Niels said, it doesn't change the retain count of observation object
  • the best is to play safe with delegate back to controller that owns table view or any other view that needs to be updated with data asynchronously.
  • always take care of delegate controllers, preventing them being autoreleased before you want it, t.i., before all asynchronous data is received, by adding popped controller to collection properties, etc...it all depends how your app is navigated and how do you want it to function
  • you can also use UINavigationControllerDelegate to cancel asynchronous transfer operations when controller delegate is dismissed, of course.

Upvotes: 0

Related Questions