Swift:使用完成处理程序从另一个通知 ViewController

Posted

技术标签:

【中文标题】Swift:使用完成处理程序从另一个通知 ViewController【英文标题】:Swift: Notifying a ViewController from another using completion handler 【发布时间】:2016-08-15 22:39:55 【问题描述】:

我的应用中有 2 个 ViewController。其中一个名为 vcA 的方法正在使用一种方法(此处为 viewDidLoad)与我的网络层(我的应用程序中的一个类)进行通信。完成网络作业(将由完成处理程序推断)后,我想通知类 vcB 调用一个方法来获取网络层提供的一些数据。 请看下面的 sudo 代码:

class Networking 

   static var PublicValue : SomeKindOfClass? = nil

   static func test(completionHandler : (successful : Bool) -> Void) -> Void 
      //Do some networking in background
      Network.BackgroundNetworking() 
         if result = true 
            PublicValue = SomeValue
            completionHandler(successful : true)
         
         else 
            completionHandler(successful : false)
         
    


class vcA : UIViewController 

   override func viewDidLoad() 
      super.viewDidLoad()

      // Do any additional setup after loading the view.
      Networking.test(completionHandler :  (successful) in
         if successful == true 
            //Here I want to notify class vcB to call printPublicValue method
         
      )
   


class vcB : UIViewController 

  func printPublicValue() 

      print(Networking.PublicValue)
   

【问题讨论】:

使用 NSNotifications 谢谢。我在这里读到过,但我不明白 B/W NSNotifications & NSNotificationCenter & performSelector & KVO 有什么区别,哪一个最适合我的情况? 【参考方案1】:

我同意@Paulw11,您应该考虑使用 NSNotifications。它们易于设置和使用,在这种情况下效果很好。为此,在您的一个视图控制器中输入以下代码:

NSNotificationCenter.defaultCenter().postNotificationName("nameOfNotification", object: nil)

在您的第二个视图控制器(将接收通知的那个)中放置:

NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(NameOfViewController.nameOfFunction(_:)), name: "nameOfNotification", object: nil)

然后你可以像这样创建一个函数:

func nameOfFunction(notif: NSNotification) 
      //Insert code here

如果您想更深入,这里有一个很棒的教程:

https://www.andrewcbancroft.com/2014/10/08/fundamentals-of-nsnotificationcenter-in-swift/

编辑:Swift 3 实现。

NotificationCenter.default.post(name: NSNotification.Name(rawValue: "nameOfNotification"), object: nil)

在您的第二个视图控制器(将接收通知的那个)中放置:

NotificationCenter.default.addObserver(self, selector: #selector(self.nameOfFunction), name: NSNotification.Name(rawValue: "nameOfNotification"), object: nil)

然后你可以像这样创建一个函数:

func nameOfFunction(notif: NSNotification) 
      //Insert code here

Swift 4 实现。

NotificationCenter.default.post(name: NSNotification.Name(rawValue: "nameOfNotification"), object: nil)

在您的第二个视图控制器(将接收通知的那个)中放置:

NotificationCenter.default.addObserver(self, selector: #selector(self.nameOfFunction), name: NSNotification.Name(rawValue: "nameOfNotification"), object: nil)

然后你可以像这样创建一个函数:

@ objc func nameOfFunction(notif: NSNotification) 
      //Insert code here

【讨论】:

感谢您的回答。这对我有用。但是如果我想从 A 类添加观察者 B 会发生什么?我真正想做的是当A类通过完成处理程序完成工作时调用B类的方法viewDidLoad 你不应该直接调用视图控制器的viewDidLoad。如果您有对 B 实例的引用,那么您可以将该对象设置为观察者(addObserver 的第一个参数),但通常一个类应该管理自己的观察。既然您说要调用viewDidLoad,实际上您应该在检索数据时触发从A到B(或呈现B)的segue,在这种情况下您不需要NSNotifications 我有一个 UITabBarViewController,所以我希望它要求网络层为我获取所有数据。在此过程之后,我想通知每个选项卡它们的数据已准备好使用。但正如您所知,它只是作为观察者添加的第一个选项卡的 ViewController(其他选项卡甚至还没有加载!)。有没有办法解决这个问题,或者我完全走错了路?! 您也可以将观察者添加到其他视图控制器。【参考方案2】:

在最新的 swift 版本中 NotificationCenter.default.post(name: NSNotification.Name(rawValue: "Name"), object: notification)

【讨论】:

以上是关于Swift:使用完成处理程序从另一个通知 ViewController的主要内容,如果未能解决你的问题,请参考以下文章

是否可以在委托方法中使用完成处理程序 - Swift

Swift导航到View from notification

从另一个文件中快速调用完成处理程序失败

Swift MVVM模式·图层分离

传递信息并从另一个线程通知一个线程的最简单方法

使用 Swift for iOS 处理来自关闭应用程序的推送通知,如何显示它然后返回关闭或暂停?