在扩展中添加和删除NotificationObserver

时间:2018-09-25 10:57:42

标签: ios swift

我有一个UILabel扩展,以及在其中添加和删除自定义NSNotification的内容。

public extension UILabel {

    @IBInspectable var localizedText: String? {

        get { return text }
        set {
            NotificationCenter.default.removeObserver(self, name: NSNotification.Name(rawValue: LCLLanguageChangeNotification), object: nil)
            NotificationCenter.default.addObserver(forName: NSNotification.Name(rawValue: LCLLanguageChangeNotification), object: nil, queue: .main) { [weak self] (notification) in
                guard let strongSelf = self else {
                    NotificationCenter.default.removeObserver(self, name: NSNotification.Name(rawValue: LCLLanguageChangeNotification), object: nil)
                    return
                }
                strongSelf.text = strongSelf.localizedText?.localized()
            }
            text = newValue?.localized()
        }
    }
}

我在此解决方案中看到的问题是

  

自我

为nil,无法删除观察者,因此即使从UIWindow堆栈中删除了UILabel,也会触发此通知。

有什么解决方法吗?

2 个答案:

答案 0 :(得分:2)

从Apple文档NotificationCenter.removeObserver

  

如果您的应用程序针对iOS 9.0和更高版本或macOS 10.11和更高版本,则无需在其dealloc方法中注销观察者。

因此,不再需要照顾持有观察者的父对象。

答案 1 :(得分:2)

据zizoft提到的Apple Docs:

  

如果您的应用定位到iOS 9.0和更高版本或macOS 10.11和更高版本,则您   不需要在其dealloc方法中注销观察者。

这非常阴暗,因为用户已经体验到它不适用于所有情况。 This is one example

该博客作者发现,只有当您获得selector推荐后,它才会被自动删除。因此,您无法像拥有开放块那样拥有开放块。相反,我会这样创建它:

extension UILabel {

        func addStuff() {
            NotificationCenter.default.addObserver(self, selector: #selector(doStuff), name: NSNotification.Name(rawValue: LCLLanguageChangeNotification), object: nil)
        }

        @objc func doStuff() {

        }
    }

主题是我将使用比您更好的名称处理程序,看看Here,它会更干净: