Why NSNotifications during dealloc are a recipe for desaster
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 autorelease
s 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.
Post a comment
All comments are held for moderation; basic HTML formatting accepted.