子类化 NotificationCenter 的优缺点

Benefits and Disadvantages for subclassing NotificationCenter

我对 Swift 很陌生。在我看到的所有NotificationCenter的例子中,都使用默认的NotificationCenter.default。但是我已经测试过可以子类化 NotificationCenter 并使用自定义对象来 post 和监听通知。

import Foundation

struct Notice {
    let num: Int
    let str: String
}

class TestObj: NotificationCenter {
    private var number = 0
    override init() {
        number = 5
    }
    
    func postNotification(_ num: Int) {
        post(name: Notification.Name(rawValue: "TestObjNotification"), object: Notice(num: num, str: "No is \(num)"))
    }
}

class Watcher: NSObject {
    var obj = TestObj()
    
    func addWatchers() {
        obj.addObserver(self, selector: #selector(watched(noti:)), name: Notification.Name(rawValue: "TestObjNotification"), object: nil)
    }
    
    func watch(num: Int) {
        obj.postNotification(num)
    }
    
    @objc func watched(noti: NSNotification) {
        print(noti.name.rawValue)
        print(noti.object!)
        guard let noticeObj = noti.object as? Notice else {
            print("Not working")
            return
        }
        print(noticeObj.num)
        print(noticeObj.str)
    }
}

let watcherObj = Watcher()
watcherObj.addWatchers()
watcherObj.watch(num: 500)

我更喜欢这种方法,因为这将确保将通知分组到特定类型,而不是为应用程序范围维护通知。也可以使用这些自定义类型为 iOS 12 及更早版本实现 ObservableObject 功能。我担心的是:

一般来说,您应该更喜欢组合而不是继承。我不建议在这里进行子类化。 TestObj 不是 通知中心。您可以配置它,以便 TestObj 有一个 通知中心,如果您愿意:

class TestObj {
    var notificationCenter: NotificationCenter
    private var number = 5
    override init(notificationCenter: NotificationCenter) {
        self.notificationCenter = notificationCenter
    }
    
    func postNotification(_ num: Int) {
        notificationCenter.post(name: Notification.Name(rawValue: "TestObjNotification"), object: Notice(num: num, str: "No is \(num)"))
    }
}

现在您无需担心任何传入的通知中心的生命周期超出 TestObj 的生命周期。