Reputation: 3357
Normally I add my observers in viewWillAppear
and remove them in viewWillDisappear
. In this case I need one of the observers to continue even after the view is gone so that it can finish some work. In order to make sure that the observer is only added once with this view, I do the following:
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:YES];
[[NSNotificationCenter defaultCenter]removeObserver:self
name:@"imageSaved"
object:nil];
[[NSNotificationCenter defaultCenter]addObserver:self
selector:@selector(postMessageWithImage:)
name:@"imageSaved"
object:nil];
}
I have performed a search through the rest of the application to ensure that this observer is NOT registered anywhere else. Unfortunately sometimes, but not all times and there is no consistent factor, the notification is fired twice. I have also ensured with breakpoints and NSLog that the postNotifcationName
is NOT called more than once. I have not been able to reproduce on the iPhone as the problem seems confined to the iPad.
In further troubleshooting I have checked that the method is being called from the same thread (no reason it wouldn't be but just to check). This problem DOES go away if I put the removeObserver
in viewWillDisappear
, however, again that is not how I need this to work.
Clearly this is a case where the observer for this is being registered twice but I cannot find a reason why that would be. As you can see from the code, any time this observer is registered it is first removed. My only other thought is whether self
could get "corrupted" such that the removeObserver
wouldn't function properly?
Upvotes: 2
Views: 2008
Reputation: 4530
Add your observer when the view will show, and remove it when will disappear.
ADD:
- (void)viewDidLoad
{
[[NSNotificationCenter defaultCenter]addObserver:self
selector:@selector(postMessageWithImage:)
name:@"imageSaved"
object:nil];
}
REMOVE:
- (void)postMessageWithImage:(NSNotification*)aNotification
{
[[NSNotificationCenter defaultCenter]removeObserver:self
name:@"imageSaved"
object:nil];
// here do your job
}
This is perfectly valid and efficient.
Upvotes: 2
Reputation: 13893
If you just want something to be executed once, put it in the predicate of a dispatch_once()
call, like
static dispatch_once_t lock;
dispatch_once(&lock, ^{
// put your addObserver call here
});
Upvotes: 0
Reputation: 2665
Instead of adding the observer in viewWillAppear:
, try adding the observer you wish to persist when the view disappears in viewDidLoad
. Then you can call your removeObserver:name:object:
in your dealloc
method
Upvotes: 0