I was trying to prepare a simple demo for using NSNotificationCenter when I got unexpected crashes, but only sometimes. I have two classes, Scout and Shouter. On -init, Shouter posts a notification to NSNotificationCenter, and Scout adds itself as an observer for the same notification on its respective -init.
When the application crashes, it has "unrecognized selector sent to instance 0x100109480" (address changes of course). This led me to check the addresses of the objects to see what happens. It appears that sometimes a Shouter init after a Scout init is overwriting the address for the Scout object.
Code is below. I'm hoping to understand why this happens. I've tried removing the id/idCounter mechanism and using a hard-coded int in case my understanding of static was wrong.
Relevant code for Shouter:
@implementation Shouter{
int _id; //An ID-code to recognize different instances of Shouter.
}
-(id)init{
NSLog(@"init test Shouter - what is self? %@", self);
if(self=[super init]){
static int _idCounter = 0;
_id = _idCounter++;
NSDictionary *dictionary = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:_id] forKey:@"ID-code"];
[[NSNotificationCenter defaultCenter] postNotificationName:@"sample" object:nil userInfo:dictionary];
}
return self;
}
@end
Relevant code for Scout:
@implementation Scout
-(id)init{
NSLog(@"init test Scout - what is self? %@", self);
if(self=[super init]){
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(messageReceived:)
name:@"sample"
object:nil];
}
return self;
}
- (void) messageReceived:(NSNotification*)notification{
NSDictionary *dictionary = [notification userInfo];
id object = [dictionary objectForKey:@"ID-code"];
int code = -1;
if([object isKindOfClass:[NSNumber class]]){
code = [((NSNumber*)object) intValue];
}
NSLog(@"Received a message from a Shouter instance. ID-code was: %i", code);
}
@end
Relevant code for main:
int main(int argc, const char * argv[])
{
@autoreleasepool {
[[Shouter alloc] init];
[[Scout alloc] init];
[[Shouter alloc] init];
}
return 0;
}
Example output in crash instance:
2014-01-23 11:38:30.800 Lab 3 Snippets[3461:303] init test Shouter - what is self? <Shouter: 0x100109480>
2014-01-23 11:38:30.802 Lab 3 Snippets[3461:303] init test Scout - what is self? <Scout: 0x1003007b0>
2014-01-23 11:38:30.803 Lab 3 Snippets[3461:303] init test Shouter - what is self? <Shouter: 0x1003007b0>
2014-01-23 11:38:30.803 Lab 3 Snippets[3461:303] -[Shouter messageReceived:]: unrecognized selector sent to instance 0x1003007b0