NSNotification 未观察或发布数据

问题描述

我正在尝试学习如何将 NSNotification 用于我正在从事的项目,因为我以前从未使用过它,所以我首先尝试先学习如何使用它;每次我尝试遵循 youtube 教程或在线找到的教程时,我的代码似乎都不起作用。此外,在尝试调试问题时,它显示代码的观察者部分没有进入@obj c 函数。下面是我的代码显示了如何使用它来发布和观察通知

    extension Notification.Name {
    static let notifyId = Notification.Name("NotifyTest")
}

ViewController.swift

class ViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        
    }

    var test: ObserverObj = ObserverObj(observerLblText: "Observing")
    @IBAction func notifyObserver(_ sender: Any) {
        let vc = storyboard?.instantiateViewController(identifier: "ObserverVC")
        vc?.modalPresentationStyle = .fullScreen
        guard let vcL = vc else {
            return
        }
        NotificationCenter.default.post(name: .notifyId,object: nil)
        self.navigationController?.pushViewController(vcL,animated: true)
    }
    
}

NotificationTestViewController.swift

import UIKit

class NotificationTestViewController: UIViewController {

    @IBOutlet weak var observerLbl: UILabel!
    override func viewDidLoad() {
        super.viewDidLoad()
        NotificationCenter.default.addobserver(self,selector: #selector(observingFunc(notification:)),name: .notifyId,object: nil)
        // Do any additional setup after loading the view.
    }
    
    @objc func observingFunc(notification: Notification) {
   
        observerLbl.text = "notifying"//text.test.observerLblText
    }

有人可以帮助我并告诉我哪里出错了,因为我已经尝试了 2 天。

解决方法

在添加观察者之前发送通知,这意味着目标控制器中的 viewDidLoad 在源视图控制器中的 post 行之后执行。

可能的解决方案是:

  1. 覆盖目标控制器中的 init(coder 并在那里添加观察者。

    required init?(coder: NSCoder) {
        super.init(coder: coder)
        NotificationCenter.default.addObserver(self,selector: #selector(observingFunc),name: .notifyId,object: nil)
    }
    
  2. 如果 init(coder 未被调用覆盖 init()

  3. 在发布通知前添加观察者(此解决方案仅用于教育目的)

    @IBAction func notifyObserver(_ sender: Any) {
        guard let vcL = storyboard?.instantiateViewController(identifier: "ObserverVC") as? NotificationTestViewController else { return }
        vcL.modalPresentationStyle = .fullScreen
        NotificationCenter.default.addObserver(vcL,selector: #selector(NotificationTestViewController.observingFunc),object: nil)
        self.navigationController?.pushViewController(vcL,animated: true) 
        NotificationCenter.default.post(name: .notifyId,object: nil)
    }
    

但是在实践中,强烈建议您不要将通知发送到您所参考的目的地。

,

原因是当您发出通知时,您的 NotificationTestViewController 尚未调用 viewdidload 方法

  class ViewController: UIViewController {
        
        override func viewDidLoad() {
            super.viewDidLoad()
            // Do any additional setup after loading the view.
            
        }

        var test: ObserverObj = ObserverObj(observerLblText: "Observing")
        @IBAction func notifyObserver(_ sender: Any) {
            let vc = storyboard?.instantiateViewController(identifier: "ObserverVC")
            vc?.modalPresentationStyle = .fullScreen
            guard let vcL = vc else {
                return
            }
            self.navigationController?.pushViewController(vcL,animated: true) 
            NotificationCenter.default.post(name: .notifyId,object: nil)
        }
        
    }