【问题标题】:Benefits and Disadvantages for subclassing NotificationCenter继承 NotificationCenter 的优点和缺点
【发布时间】:2021-06-10 07:13:34
【问题描述】:

我对 Swift 很陌生。在我见过的所有NotificationCenter 的例子中,都使用了默认的NotificationCenter.default。不过我已经测试过,可以将NotificationCenter 子类化并使用自定义对象来发布和收听通知。

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 功能。我担心的是:

  • 这会导致性能损失吗?
  • 当自定义NotificationCenter 被解除分配时会发生什么?所有听众都需要停止听吗?当所有侦听器注册相同的通知时会发生什么。由于NotificationCenter.default 是只读的,因此没有任何问题。

【问题讨论】:

    标签: ios swift objective-c


    【解决方案1】:

    通常,您应该更喜欢组合而不是继承。我不建议在这里进行子类化。 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 的生命周期。

    【讨论】:

      猜你喜欢
      • 2012-05-29
      • 2011-05-04
      • 1970-01-01
      • 2023-03-11
      • 1970-01-01
      • 2010-09-20
      • 2011-01-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多