【问题标题】:Notify all loaded ViewControllers of a certain event通知所有加载的 ViewController 某个事件
【发布时间】:2012-08-09 06:59:24
【问题描述】:

我有一个类每隔一段时间在后台同步数据。用户可以在应用导航树中的任何位置,无论用户在哪里,我都需要能够使用我刚刚同步的任何新数据来更新视图控制器。

我把负责后台线程同步的对象作为 SharedAppDelegate 的一个属性。

在某种程度上,我需要实现类似于观察者模式的东西,并且每次实例化视图控制器时都将其设置为侦听后台同步对象上的某些事件,以便在每次同步后我可以在视图控制器中执行一个方法正在听。

我不确定在 Objective-C 中执行此操作的正确方法是什么,或者是否有更好或推荐的方法。

【问题讨论】:

    标签: objective-c ios viewcontroller


    【解决方案1】:

    使用NSNotificationNSNotificationCenter,这完全符合您的目的:

    • 在您的 AppDelegate 中,当同步结束时,调用

      [[NSNotificationCenter defaultCenter] postNotificationName:@"SyncEnded" object:mySyncObject]
      
    • 在您显示的每个视图控制器中,调用

      _myObserver = [[NSNotificationCenter defaultCenter] addObserverForName:@"SyncEnded" object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note){ ...your UI refresh code... }
      
    • 也不要忘记在不再需要观察者时将其移除(视图控制器已释放/卸载/不可见,由您决定),否则NSNotificationCenter 将最终崩溃:

      [[NSNotificationCenter defaultCenter] removeObserver:_myObserver];
      

    一些注意事项:

    此示例使用基于块的 API 在主操作队列上执行 UI 刷新工作(隐含在主线程上),因为您不得在主线程以外的任何其他线程上执行 UIKit 操作。这很可能您的后台同步将在其他线程上发送通知,因此需要切换到主线程。如果您想使用基于选择器的 API,请务必在主线程上发送通知。

    您可以根据需要在通知上注册任意数量的观察者,因此这与您的模式完美匹配(NSNotifications 通常是通知不同应用组件有关应用范围事件(如同步结束)的最佳方式)。

    发布通知时传递的object 参数允许您在需要时使用note.object 访问观察者块中的同步对象。

    【讨论】:

    • 这非常有效。我只有一个问题,您链接到的 Apple 文档中没有提到。移除观察者应该在 ARC 下的 viewDidUnload 中完成,对吧?这看起来应该进入 dealloc,但我认为我不应该在 ARC 下使用它。
    • 您可以使用 dealloc,即使是使用 ARC,也可以取消注册观察者(或释放对象使用的任何资源,但现在由 ARC 管理的实例变量和属性除外)。只是不要在你的实现中调用[super dealloc](无论如何clang不会让你这样做)。
    • 知道了,谢谢。顺便说一句,我已经在我的应用程序中实现了它,并且效果很好!
    猜你喜欢
    • 2019-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多