[12] Unregister block-based NotificationCenter observer

Do you have to manually unregister block-based NotificationCenter observers?


final class NotificationToken {
    
    private let notificationCenter: NotificationCenter
    private let token: NSObjectProtocol
    
    init(notificationCenter: NotificationCenter = .default, token: NSObjectProtocol) {
        self.notificationCenter = notificationCenter
        self.token = token
    }
    
    deinit {
        notificationCenter.removeObserver(token)
    }
    
    func add(to bag: NotificationTokenBag) {
        bag.add(token: self)
    }
}

final class NotificationTokenBag {
    
    private var tokens: [NotificationToken] = []
    
    func add(token: NotificationToken) {
        tokens.append(token)
    }

}

protocol Disposable {
    func dispose()
}

extension NotificationToken: Disposable {
    func dispose() {
        notificationCenter.removeObserver(token)
    }
}

extension NotificationTokenBag: Disposable {
    func dispose() {
        tokens.removeAll()
    }
}

extension NotificationCenter {
    func observe(forName name: NSNotification.Name?, object obj: Any?, queue: OperationQueue?, using block: @escaping (Notification) -> Swift.Void) -> NotificationToken {
        let token = addObserver(forName: name, object: obj, queue: queue, using: block)
        return NotificationToken(notificationCenter: self, token: token)
    }
}

class MyClass {
    
    private var token: NotificationToken?
    
    init() {
        token = NotificationCenter.default.observe(forName: nil, object: nil, queue: nil) { (noti) in
            
        }
    }

}

class MyClass2 {
    
    private let bag = NotificationTokenBag()
    
    init() {
        NotificationCenter.default.observe(forName: nil, object: nil, queue: nil) { (noti) in
            
        }.add(to: bag)
    }
}