繁体   English   中英

如何在Swift iOS中注销NSNotification

[英]How to unregister an NSNotification in Swift iOS

我有两个控制器

class CtrlA: UIViewController {
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        NotificationCenter.default.addObserver(CtrlB.self, selector: #selector(CtrlB.badge(notification:)), name: NSNotification.Name(rawValue: "badge"), object: nil)
    }

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)

        NotificationCenter.default.removeObserver(CtrlB.self, name: NSNotification.Name(rawValue: "badge"), object: nil)
    }
}

class CtrlB: UIViewController {
    static func badge (notification: NSNotification) {
        // blah blah
    }
}

注销上面的通知侦听器的正确方法是什么? 我不确定这是正确的: NotificationCenter.default.removeObserver(CtrlB.self, name: NSNotification.Name(rawValue: "badge"), object: nil)

我也不认为可以使用self ,因为它是在CtrlB.selfCtrlB.self

我不确定为什么要使用类而不是实例来注册/注销通知。 'CtrlB.self'-不会为您提供CtrlB类的实例,实际上它将返回一个类本身。 相反,您应该使用以下内容:

class CtrlA {

    let ctrlBInstance = CtrlB()

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        NotificationCenter.default.addObserver(ctrlBInstance, selector: #selector(CtrlB.badge(notification:)), name: NSNotification.Name(rawValue: "badge"), object: nil)
    }

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)

        NotificationCenter.default.removeObserver(ctrlBInstance, name: NSNotification.Name(rawValue: "badge"), object: nil)
    }
}

在这种情况下,您的ClassB应该看起来像这样:

class CtrlB {
   func badge (notification: NSNotification) {
        // blah blah
    }
}

因此,在项目中实现通知的最佳方法是在内部创建一个称为NotificationManager类,该类声明一本词典,您可以在其中始终更新观察者

class NotificationManager {
var observers = [String: AnyObject]()
}

在同一类中创建addObserver方法,发布通知方法并删除观察者方法。

func postNotification(_ name: String, userInfo: [AnyHashable: Any]? = nil) {
    NotificationCenter.default.post(name: name, object: nil, userInfo: userInfo)
}

func addObserver(_ name: String, block: @escaping (Notification) -> Void) {
 //if observer is already in place for this name, remove it
  removeObserverForName(name)
  let observer = NotificationCenter.default.addObserver(forName: name), object: nil, queue: OperationQueue.main, using: block)
  self.observers[name] = observer
}

func removeObserver(_ name: name) {
 guard let observer = self.observers[name] else { return }
 NotificationCenter.default.removeObserver(observer)
 self.observers.removeValue(forKey: name)
}

 //Removes all observers
func removeAllObservers() {
for observer in self.observers.values {
 NotificationCenter.default.removeObserver(observer)
 }self.observers = [:]
}

因此,在您需要的任何类中访问上述方法,无论需要使用什么方法,它都会处理一切。 这也可以防止代码崩溃。 如果尝试多次删除同一观察者。

您需要获取未声明的观察者实例。

例如,您需要设置类变量secondA ...

class CtrlA: UIViewController {

var secondController: CtrlB?


override func viewDidLoad()
{
super.viewDidLoad()

    if let unwrappedController = storyboard.instantiateViewController(withIdentifier: "someViewController") as? CtrlB
    {
    secondController = unwrappedController        
    }

}

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    if let secondController = secondController
    {
    NotificationCenter.default.addObserver(CtrlB.self, selector: #selector(CtrlB.badge(notification:)), name: NSNotification.Name(rawValue: "badge"), object: nil)
    }
}

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    if let secondController = secondController
    {
    NotificationCenter.default.removeObserver(CtrlB.self, name: NSNotification.Name(rawValue: "badge"), object: nil)
    }
}

//Also don't forget to remove listening on deinit

deinit
{
    if let secondController = secondController
    {
    NotificationCenter.default.removeObserver(secondController, name: NSNotification.Name(rawValue: "badge"), object: nil)
    }
  }
}

    class CtrlB: UIViewController {
        //Here you go with notification...
        static func badge (notification: NSNotification) {
            // blah blah
        }
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM