There was a Mulle internal discussion a year back about the use of
dealloc notifications in some framework. Here is a little demo code that shows, that
dealloc notifications - or notifications during
dealloc in general - are not a good idea.
#import <Foundation/Foundation.h>
#import <Foundation/NSDebug.h>
@interface Problem : NSObject
{
}
@end
@implementation Problem
- (void) dealloc
{
NSNotification *notification;
notification = [NSNotification notificationWithName:@"AsIDie"
object:self];
// it's synchronous... yet...
[[NSNotificationCenter defaultCenter] postNotification:notification];
[super dealloc];
}
@end
int main (int argc, const char *argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSZombieEnabled = YES;
[[[Problem alloc] init] release];
[pool release];
return( 0);
}
This is the output:
2003-09-13 14:50:36.772 DeallocNotification[1679] *** *** Selector 'release' sent to dealloced instance 0x54450 of class Problem.
Break at '-[_NSZombie release]' to debug.
2003-09-13 14:50:36.784 DeallocNotification[1679] *** -[NSAutoreleasePool dealloc]: Exception ignored while releasing an object in an autorelease pool: NSGenericException *** Selector 'release' sent to dealloced instance 0x54450 of class Problem.
Break at '-[_NSZombie release]' to debug.
The problem is that NSNotification retains and subsequently autoreleases the object. The object is retained while in the process of deallocation. release and dealloc will be now called one more time from the NSAutoreleasePool, when it dies. But the deallocation can't be stopped now. This will lead to - possibly quite subtle - crashes.
Bottomline, keep the dealloc routine as stupid as possible to save yourself some trouble.