NSNotificationCenter、ViewWillAppear、ViewWillDisappear 和 ViewDidDisappear

NSNotificationCenter, ViewWillAppear, ViewWillDisappear and ViewDidDisappear

this Whosebug answer 中所见,关于

"NSNotificationCenter with respect to ViewWillAppear and ViewWillDisappear"

我们指出以下方向是首选方法

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

this other Whosebug answer 中也建议采用这种方法。

我的问题是双重的

  1. 为什么苹果的AVCam Sample Code在“AAPLCameraViewController.mremoveObserversviewDidDisappear 而不是上述答案所建议的 viewWillDisappear

  2. 为什么他们在[super viewWillAppear:animated];之后利用addObservers 而他们 removeObservers 之前 [super viewDidDisappear:animated];

从“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];
}

在何处添加和删除观察者取决于您的需要。在许多情况下,您可能希望在 init... 方法之一或 viewDidLoad 中添加观察者,并在 dealloc.

中将其删除

无论如何,应该有某种对称性,所以每次添加它都会被删除一次。

添加 viewWillAppearviewDidAppear 之间确实没有实际区别,删除 viewWillDisappearviewDidDisappear 之间确实没有实际区别。在这些差异很重要的地方,这将是一个罕见的通知。添加或删除是在调用 [super ...].

之前还是之后完成的相同

Apple 的例子是一个很好的榜样。事情在视图显示之前设置并在视图消失后清理。但同样,这实际上取决于您正在处理什么通知以及您希望何时收听通知。

问问自己何时需要了解通知。是在视图控制器的整个生命周期内吗?只是在可见的时候吗?是从可见之前到不可见之后?

该问题的答案决定了添加和删除观察者的最佳方法。

可以证明 viewWillAppear 和 viewDidDisappear 是平衡对,而不是 viewWillAppear 和 viewWillDisappear。思路是在viewWillAppear中设置,view可见前,removed后在viewDidDisappear中清理。您的代码将在视图可见的整个持续时间内保持不变。

没有单一的 rule/way 来注册监听事件和取消注册。这完全取决于要求和程序流程。

关于您的问题:

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

Apple 的示例代码主要处理用户交互。因此它需要观察用户实际可以看到视图并与之交互的事件。观察者在 viewDidDisappear 中被移除,因为此时可以确定用户将无法再与视图交互。 viewWillDisappear定义了view-controller生命周期中的一个状态,view即将被移除但还没有被移除yet.So,理论上最好停止监听一个事件,当它不会再发生(这里是 viewDidDisappear)。虽然,即使在 viewWillDisappear 中取消注册事件,代码也可能会工作,但是,在某些情况下,编码器可能会在 viewWillDisappear 的主线程上放置大量代码并停止监听事件.在这种情况下,可能会错过一些事件。

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

观察者添加到 viewWillAppear 因为事件的事件生命周期即将开始(用户与视图交互)。事件是否被注册并不重要 before/after [super viewDidDisappear:animated]。根据面向 objective 的语言遵循的编程架构,子 类 的清理先于它的 parent/super 类。因此,子级中的清理(删除观察者)是在父级中的清理之前完成的。在 viewWillAppear 中添加观察者并在 viewDidDisappear 中移除观察者确保在事件开始之前添加观察者并在事件结束后结束(程序要求)。

我对 NSNotificationCenter 实现有什么考虑?

  1. 需要观察者的事件生命周期。
  2. 什么时候注册活动?(在活动即将开始之前)
  3. 何时取消注册活动?(活动结束后)。
  4. 注销活动后需要进行的任何清理工作。

**添加 viewWillAppear 有一些其他 AVFoundation 特定原因,但上面的解释应该总结了症结所在。

示例代码尝试在控制器的视图对用户不可见时创建和删除观察者(因此之前出现和之后消失)以增强用户体验(例如,避免空白屏幕,或在视图可见时重绘)。

至于第二个问题,似乎主要是偏好。我也是这样做的:一个子类让父类先初始化,最后取消初始化。