I have an 'internet aware' base class for objects which require networking in my app. All the objects which need to be internet aware inherit from it. As you can imagine I allocate and deallocate a lot of these objects.
The internet aware base class has the following code to interact with the Reachability classes used to check for internet status.
#import "Reachability.h"
- (id) init {
...
self.internetReachable = [Reachability reachabilityForInternetConnection];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(checkNetworkStatus) name:kReachabilityChangedNotification object:nil];
[self.internetReachable startNotifier];
...
}
- (void) dealloc
{
[self.internetReachable stopNotifier];
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
As soon as there is a change in internet status in my app, the app crashes with the following error:
*** -[Reachability isKindOfClass:]: message sent to deallocated instance 0x1e249a30
Ive turned on zombies and tracked the problem down to the following line of code within Reachability.m
NSCAssert([(NSObject*) info isKindOfClass: [Reachability class]], @"info was wrong class in ReachabilityCallback");
Unfortunately, beyond stopping listening for NSNotifcations and stopping the notifier, im not sure what else my objects can do to avoid this error.
Any help or suggestions would be great.
Thanks
Vb
Edit:
OK so following the advice of the answer below I ran it in instruments with allocations and this was the retain count history.
It is as I suspected, its an object that I have deallocated being called by Foundation (ie. NSNotifcationCenter) and not myself.
My internet objects have a strong pointer to a Reachability object. When they are deallocated, so is the Reachability object. The zombie is the Reachability object. In the dealloc of my internet object I have called removeObserver, but foundation is still calling the deallocated object. I can't understand why...
The NSCAssert line is where you first access the deallocated object, but if you want to know more about the object's life cycle you should use Instruments. Use Xcode's Profile tool to run your program in the simulator with the Allocations (but not leaks!) tool. In the allocations tool's launch configuration turn on Enable NSZombie Detection and Record Reference Counts. When you hit the NSCAssert line Instruments should detect the attempt to message the zombie info object and make a note of it. If you look at the detailed information for the zombie info object Instruments will show you its history of reference counts and you should be able to see when it was deallocated.