0

As seen in this stackoverflow answer about

"NSNotificationCenter with respect to ViewWillAppear and ViewWillDisappear"

We are pointed in the direction of the below as the preferred approach

"Registering the notification in viewWillAppear and unregistering it in viewWillDisappear seems to be a clean and symmetric solution to me."

This is approach is also suggested in this other stackoverflow answer.

My Question is twofold

  1. Why does Apple's AVCam Sample Code in "AAPLCameraViewController.m" removeObservers in viewDidDisappear and not viewWillDisappear as the above answers suggested.

  2. Why do they utilise addObservers after [super viewWillAppear:animated]; while they removeObservers before [super viewDidDisappear:animated];

Code Extracted from "AAPLCameraViewController.m"

- (void)viewWillAppear:(BOOL)animated {
  [super viewWillAppear:animated];

  dispatch_async(self.sessionQueue, ^{
    switch (self.setupResult) {
    case AVCamSetupResultSuccess: {
      // Only setup observers and start the session running if setup succeeded.
      [self addObservers];
      [self.session startRunning];
      self.sessionRunning = self.session.isRunning;
      break;
    }
}

- (void)viewDidDisappear:(BOOL)animated {
  dispatch_async(self.sessionQueue, ^{
    if (self.setupResult == AVCamSetupResultSuccess) {
      [self.session stopRunning];
      [self removeObservers];
    }
  });

  [super viewDidDisappear:animated];
}
Community
  • 1
  • 1
RĂ­omhaire
  • 3,084
  • 4
  • 25
  • 40

4 Answers4

1

Where you add and remove the observers depends on your needs. In many cases you would want to add the observer in one of the init... methods or viewDidLoad and remove it in dealloc.

Regardless, there should be some sort of symmetry so it is removed once for each time it is added.

There's really no practical difference between adding in viewWillAppear and viewDidAppear and there's really no practical difference between removing in viewWillDisappear and viewDidDisappear. It will be a rare notification where those differences matter. Same for whether the addition or removal is done before or after the call to [super ...].

Apple's example is a good model to follow. Things are setup before the view is displayed and cleaned up after the view is gone. But again, it really depends on what notification you are dealing with and when you want to listen for the notification.

Ask yourself when you need to know about the notification. Is it during the entire lifetime of the view controller? Is it only while it's visible? Is it from just before it's visible to just after it's not?

The answer to that question determines the best methods to add and remove the observer.

rmaddy
  • 314,917
  • 42
  • 532
  • 579
1

A case can be made that viewWillAppear and viewDidDisappear are the balanced pair not viewWillAppear and viewWillDisappear. The thinking is to set up in viewWillAppear, before the view is visible, and to clean up in viewDidDisappear after it's removed. Your code will be in place for the entire duration that the view is visible.

Kevin Snow
  • 129
  • 3
  • 1
1

There is no single rule/way to register for listening to an event and unregister for the same. It totally depends on the requirements and program flow.

As for your questions:

1)Why does Apple's AVCam Sample Code in "AAPLCameraViewController.m" removeObservers in viewDidDisappear and not viewWillDisappear as the above answers suggested.

The Apple's sample code basically deals with the user interactions. So it needs to observe the events when user can actually see the view and interact with it. The observer is removed in viewDidDisappear as it is certain at this point of time that the user would not be able to interact with the view anymore. viewWillDisappear defines a state in view-controller's lifecycle that the view is about to be removed but hasn't been removed yet.So, in theory it's better to stop listening to an event when it would not occur anymore(Here viewDidDisappear). Although, the code might work even if the event is unregistered in viewWillDisappear, but , in certain cases, the coder might have put a lot of code on main thread in viewWillDisappear and stopped listening to events. In this case, some events might be missed.

2)Why do they utilise addObservers after [super viewWillAppear:animated]; while they removeObservers before [super viewDidDisappear:animated];

The observer is added on viewWillAppear because the event lifecycle for the event is gonna start(User interacting with view). It does not really matter whether event is registered before/after [super viewDidDisappear:animated]. According to the programming architectures followed in objective oriented languages, the cleanup of child classes precedes it's parent/super classes. So, the cleanup(removing observer) in child is done before cleanup in Parent. Adding observer in viewWillAppear and removing in viewDidDisappear ensures that observer is added before event started and ended after the event ended(What the program requires).

What i consider for NSNotificationCenter implementations?

  1. Life-cycle of event that is gonna need observers.
  2. When to register for an event?(Before event is about to start)
  3. When to unregister for an event?(After event has ended).
  4. Any cleanup needed after unregistering events.

**There a few other AVFoundation specific reasons for adding on viewWillAppear, but the explanation above should sum up the crux.

Abhishek Singh
  • 6,068
  • 1
  • 23
  • 25
0

The sample code attempts to create and remove observers when the controller's view is not yet visible to the user (hence the before appear and after disappear) so as to enhance the user's experience (avoid blank screens, for instance, or redraw while the view is visible).

As for the second question, it appears to be mostly a preference. I do the same: a subclass lets the parent initialize first, and de-initialize last.

Dimitry
  • 6,545
  • 2
  • 20
  • 21