NSNotification leads to segmentation fault
Asked Answered
K

2

6

I have a strange behavior with an NSNotification object.
My app has an navigation controller, first view is a table view and the second view is just a view controller which shows data of the selected cell.
So in this data view controller I send a notification when I press a button. The notification also works at first.

BUT when I go back to the table view and push the data view controller on stack again and touch the button with the notification, the whole app crashes with no error log.
Xcode only highlights this line:

[[NSNotificationCenter defaultCenter] 
 postNotificationName:@"toggleNoteView" object:nil];

The function where I send the notification:

- (IBAction) toggleNoteView: (id) sender
{
    [[NSNotificationCenter defaultCenter] 
    postNotificationName:@"toggleNoteView" object:nil];
}

This is the receiver:

- (id)init {
    [[NSNotificationCenter defaultCenter] addObserver:self 
                                         selector:@selector(toggleNoteView:) 
                                             name:@"toggleNoteView" object:nil];
     ...
}

- (void) toggleNoteView:(NSNotification *)notif  {

    takingNotes = !takingNotes;
}

Edit: Now I did get some error logs.

2011-06-27 23:05:05.957 L3T[3228:707] -[UINavigationItemView toggleNoteView:]: unrecognized selector sent to instance 0x4b235f0
2011-06-27 23:05:06.075 L3T[3228:707] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UINavigationItemView toggleNoteView:]: unrecognized selector sent to instance 0x4b235f0'
*** Call stack at first throw:
(
0   CoreFoundation                      0x3634f64f __exceptionPreprocess + 114
1   libobjc.A.dylib                     0x370a2c5d objc_exception_throw + 24
2   CoreFoundation                      0x363531bf -[NSObject(NSObject) doesNotRecognizeSelector:] + 102
3   CoreFoundation                      0x36352649 ___forwarding___ + 508
4   CoreFoundation                      0x362c9180 _CF_forwarding_prep_0 + 48
5   Foundation                          0x35c45183 _nsnote_callback + 142
6   CoreFoundation                      0x3631e20f __CFXNotificationPost_old + 402
7   CoreFoundation                      0x362b8eeb _CFXNotificationPostNotification + 118
8   Foundation                          0x35c425d3 -[NSNotificationCenter postNotificationName:object:userInfo:] + 70
9   Foundation                          0x35c441c1 -[NSNotificationCenter postNotificationName:object:] + 24
10  L3T                                 0x0003d17f -[Container toggleNoteView:] + 338
11  CoreFoundation                      0x362bf571 -[NSObject(NSObject) performSelector:withObject:withObject:] + 24
Khan answered 27/6, 2011 at 20:49 Comment(0)
B
8

Don't forget to remove the observer when you unload a view. Basically what's happening is when you post a notification to a non-existing view it can't run the selector, thus crashing your app.

-(void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self];
    [super dealloc];
}
Bello answered 28/6, 2011 at 0:44 Comment(0)
P
3

From your description, it seems like every time you push a view controller, you're creating a new instance of the view controller to do that.

If that's the case, you need to first make sure you aren't leaking that view controller when you go back to the table view.

Then, in that object's dealloc method, unsubscribe it from the notifications.

-(void)dealloc {
     [[NSNotificationCenter defaultCenter] removeObserver:self];
     //other deallocation code
     [super dealloc];
}
Premiere answered 28/6, 2011 at 0:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.