1

Brief : I have a queue that sends notifications. A view controller subscribes to them and when it receives them it displays an image.

Problem : the first time, everything goes well. When I come back later to the view, I see the log that the notification was received but the image is not displayed.

Note : the background thread is a queue : dispatch_queue_create("scan", DISPATCH_QUEUE_SCAN) and from this queue the notification are posted.

@property(strong, nonatomic) id observer;

- (void)viewDidAppear:(BOOL) animated {
  [super viewDidAppear:animated];
  self.observer = [[NSNotificationCenter defaultCenter] addObserverForName:MY_NOTIF object:nil queue:nil usingBlock:^(NSNotification *note) {
    dispatch_async(dispatch_get_main_queue(), ^{
      NSLog(@"notification");
      [self.img setImage:[UIImage imageNamed:@"register-ok"]];
      [self.img setNeedsDisplay];  // useless
    });
  }
}

- (void)viewDidDisappear:(BOOL) animated {
  [super viewDidDisappear:animated];
  [[NSNotificationCenter defaultCenter] removeObserver:observer name:MY_NOTIF object:nil];
}

This is really getting me crazy. Thanks in advance for your help

EDIT : changes done :

NSLog(@"viewDidAppear. createObserver. self: %@");
[[NSNotificationCenter defaultCenter] addObserverForName:MY_NOTIF object:nil queue:nil usingBlock:^(NSNotification *note) {
  NSLog(@"will call redraww. self: %@");
  [self performSelectorOnMainThread:@selector(redraww:) withObject:nil waitUntilDone:YES];
}

-(void) redraww:(NSObject*)input {
    NSLog(@"redraww self : %@", self);
    [self.img setImage:[UIImage imageNamed:@"register-ok"]];
}

-(void) onRegistrationFinish {
  NSLog(@"remove observer. self %@", self);
  [[NSNotificationCenter defaultCenter] removeObserver:self name:(NSString *)NOTIF_SOLE_UUID object:nil];
}

console log

viewDidAppear. createObserver self: <RegisterLeftViewController: 0x15e34550>
will call redraww. self:<RegisterLeftViewController: 0x15e34550>
redrawww self : <RegisterLeftViewController: 0x15e34550>
remove observer. self <RegisterLeftViewController: 0x15e34550>

************************* Second time

viewDidAppear. createObserver self: <RegisterLeftViewController: 0x15e98ba0>
will call redraww. self:<RegisterLeftViewController: 0x15e34550>
redrawww self : <RegisterLeftViewController: 0x15e34550>
remove observer. self <RegisterLeftViewController: 0x15e98ba0>
Thomas
  • 8,306
  • 8
  • 53
  • 92
  • 2
    Also remove the observer in dealloc. use `[[NSNotificationCenter defaultCenter] removeObserver: self.observer];` – Midhun MP Jan 20 '15 at 23:31
  • With regard to your "first bad thing" - you are registering the observer in `viewDidLoad` so I would expect the behaviour you describe - notifications received as soon as the view is (re)loaded. Or, perhaps I am misunderstanding and you haven't reloaded the view at the point where you are seeing the unexpected messages, in which case I would suspect you have more than one instance of the view controller and on one of them the removeObserver hasn't been called. – Paulw11 Jan 21 '15 at 00:24
  • @Paulw11 this could be a problem but I call `stopObserving` and I am sure it is called – Thomas Jan 21 '15 at 08:47
  • @Paulw11 any idea for the second bad thing ? – Thomas Jan 21 '15 at 08:47
  • @MidhunMP dealloc doesn't get called. to go from one screen to another I use `UIViewController* vc = [self.storyboard instantiateViewControllerWithIdentifier:@"xxx"];` and `[self.navigationController.view.window setRootViewController:vc];` – Thomas Jan 22 '15 at 10:08
  • Few things: * Move addObserver to viewDidLoad and removeObserver to dealloc * Try modifying other view elements instead of images. It's possible self.img is nil on the callback block * Use the debugger, and present more info in the question about what's nil and what's not. – CVertex Jan 24 '15 at 15:51
  • @CVertex I have moved the Notification handling to `viewDidLoad` / `dealloc` but it doesn't change anything (it was like that before) Nothing is nil. I have tried changing the title of a button, same problem : works the first time I am on the view, not the other times (after viewController is dismissed and shown again later) – Thomas Jan 24 '15 at 16:13
  • @Thomas that's useful.. The fact the title is not being updated indicates the UI is being updated from the wrong thread. Try just updating the uibutton title after a delay back on the main thread. Show us your new code and proper console output after various events. FYI, I'm in trial and error mode.. – CVertex Jan 25 '15 at 02:46
  • Also try performOnMainThread and see if that changes things. performOnMainThread gets dispatched in a different way. See http://stackoverflow.com/questions/7670607/how-do-i-post-a-nsnotification-when-using-grand-central-dispatch?rq=1 – CVertex Jan 25 '15 at 02:55
  • @CVertex I have tried performOnMainThread and perfOnMainThread + with delay (imbricated) , same behaviour : image got displayed the first time but not the second. Good idea for the logs, it seems we have a culprit here !!! see question edit – Thomas Jan 25 '15 at 10:44
  • @CVertex ok, now that you helped finding the culprit I found the answer : http://stackoverflow.com/questions/23455956/ios-nsnotificationcenter-observer-not-being-removed self.observer was not working. I let you write an answer so that you can get the bounty. I am pretty sure I tried logging objects before but I think it was self.img that I was logging. Address was the same so it didn't help. – Thomas Jan 25 '15 at 11:12
  • @Thomas Cool. Is my answer what you're after? – CVertex Jan 27 '15 at 23:18

1 Answers1

0

Seems like you're doing a few things that could cause trouble.

The trouble could be coming from a number of places. Here's some things that may fix the problem:

Hope that helps

Community
  • 1
  • 1
CVertex
  • 17,997
  • 28
  • 94
  • 124
  • Actually the right way of doing things was : 1) log the self pointer and realize the notification was remembering the 1st notification block 2) move to viewDidLoad/dealloc didn't help 3) Somehow iOS optimiazes UIImages. Before asking here I logged self.img (on viewDidLoad and in notification) instead of self and it was the same, so not indicating a problem – Thomas Jan 28 '15 at 11:15