0

NSNotificationCenter用来在我的代码中发送本地通知并在 Objective-C 和 Swift 中工作。我正在从 Objective-C 发布通知并在 Swift 中接收。但是我在通知中添加的方法被多次调用并且仅在viewDidLoad方法中添加了观察者。

迅速:

override func viewDidLoad() {
    super.viewDidLoad()

    NotificationCenter.default.addObserver(self, selector:#selector(MainScreen.serverCardSynced), name: NSNotification.Name(rawValue: NOTIF_SERVER_CARD_SYNCED), object: nil);
    NotificationCenter.default.addObserver(self, selector:#selector(MainScreen.checkForAutoSync), name: NSNotification.Name.UIApplicationWillEnterForeground, object: nil);
    NotificationCenter.default.addObserver(self, selector:#selector(MainScreen.initateSync), name: NSNotification.Name(rawValue: NOTIF_CONTACT_ENTITY_CHANGE), object:nil);
    NotificationCenter.default.addObserver(self, selector:#selector(MainScreen.menuRemoved), name: NSNotification.Name(rawValue: NOTIF_MENU_REMOVED), object:nil);
    NotificationCenter.default.addObserver(self, selector:#selector(MainScreen.reloadAllCards(_:)), name: NSNotification.Name(rawValue: NOTIF_RELOAD_ALL_CARDS), object:nil);
    NotificationCenter.default.addObserver(self, selector:#selector(MainScreen.initateDownloadMyCards), name: NSNotification.Name(rawValue: NOTIF_DOWNLOAD_CARD), object:nil);
}

目标-C:

- (void)applicationDidBecomeActive:(UIApplication *)application {
    self.isSyncPending = true;
    [[NSNotificationCenter defaultCenter] 
    postNotificationName:NOTIF_CONTACT_ENTITY_CHANGE object:nil];
}

-(void)insertData(){
    [[NSNotificationCenter defaultCenter] 
    postNotificationName:NOTIF_SERVER_CARD_SYNCED object:nil];
}

我在我的中添加了删除观察者,deinit但它甚至没有调用。如何停止多次调用。

4

3 回答 3

0
//call this method in viewDidLoad
fileprivate func registerNotifs() {

    //remove observer before adding to make sure that it is added only once

    NotificationCenter.default.removeObserver(self, name: NSNotification.Name(rawValue: NOTIF_SERVER_CARD_SYNCED), object: nil)
    NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIApplicationWillEnterForeground, object: nil)
    NotificationCenter.default.removeObserver(self, name: NSNotification.Name(rawValue: NOTIF_CONTACT_ENTITY_CHANGE), object: nil)
    NotificationCenter.default.removeObserver(self, name: NSNotification.Name(rawValue: NOTIF_MENU_REMOVED), object: nil)
    NotificationCenter.default.removeObserver(self, name: NSNotification.Name(rawValue: NOTIF_RELOAD_ALL_CARDS), object: nil)
    NotificationCenter.default.removeObserver(self, name: NSNotification.Name(rawValue: NOTIF_DOWNLOAD_CARD), object: nil)

    NotificationCenter.default.addObserver(self, selector:#selector(MainScreen.serverCardSynced), name: NSNotification.Name(rawValue: NOTIF_SERVER_CARD_SYNCED), object: nil);
    NotificationCenter.default.addObserver(self, selector:#selector(MainScreen.checkForAutoSync), name: NSNotification.Name.UIApplicationWillEnterForeground, object: nil);
    NotificationCenter.default.addObserver(self, selector:#selector(MainScreen.initateSync), name: NSNotification.Name(rawValue: NOTIF_CONTACT_ENTITY_CHANGE), object:nil);
    NotificationCenter.default.addObserver(self, selector:#selector(MainScreen.menuRemoved), name: NSNotification.Name(rawValue: NOTIF_MENU_REMOVED), object:nil);
    NotificationCenter.default.addObserver(self, selector:#selector(MainScreen.reloadAllCards(_:)), name: NSNotification.Name(rawValue: NOTIF_RELOAD_ALL_CARDS), object:nil);
    NotificationCenter.default.addObserver(self, selector:#selector(MainScreen.initateDownloadMyCards), name: NSNotification.Name(rawValue: NOTIF_DOWNLOAD_CARD), object:nil);
}
于 2018-03-10T07:57:49.693 回答
0

NSNotificationCenter 是一种“发布-订阅”机制,其中每个发布的通知都会传递给所有订阅者(称为观察者)。如果您多次收到通知,则意味着您有多个订阅者,或者您正在多次发送通知。

我假设每种通知类型只有一个订阅者——Swift 中的 MainScreen UIViewController。这意味着您可能多次发送每个通知。

例如applicationDidBecomeActive被多次调用(每次应用程序激活时)。如果您想在第一次之后停止回复此通知,您可以在第一次收到后立即取消订阅:

@objc
func initateSync {
    // do something first time
    // ...

    // unsubscribe to not receive it anymore
    NotificationCenter.default.removeObserver(self,
        name: NSNotification.Name(rawValue: NOTIF_CONTACT_ENTITY_CHANGE),
        object: nil)    
}

这就是您在收到不喜欢的报纸试用后在现实世界中所做的事情:)

于 2018-03-11T22:24:11.940 回答
0

你可以这样做

fileprivate func registerLocalNotifications() {

    NotificationCenter.default.addObserver(self, selector:#selector(MainScreen.serverCardSynced), name: NSNotification.Name(rawValue: NOTIF_SERVER_CARD_SYNCED), object: nil)
    NotificationCenter.default.addObserver(self, selector:#selector(MainScreen.checkForAutoSync), name: NSNotification.Name.UIApplicationWillEnterForeground, object: nil)
    NotificationCenter.default.addObserver(self, selector:#selector(MainScreen.initateSync), name: NSNotification.Name(rawValue: NOTIF_CONTACT_ENTITY_CHANGE), object:nil)
    NotificationCenter.default.addObserver(self, selector:#selector(MainScreen.menuRemoved), name: NSNotification.Name(rawValue: NOTIF_MENU_REMOVED), object:nil)
    NotificationCenter.default.addObserver(self, selector:#selector(MainScreen.reloadAllCards(_:)), name: NSNotification.Name(rawValue: NOTIF_RELOAD_ALL_CARDS), object:nil)
    NotificationCenter.default.addObserver(self, selector:#selector(MainScreen.initateDownloadMyCards), name: NSNotification.Name(rawValue: NOTIF_DOWNLOAD_CARD), object:nil)
}

在viewDidLoad和中添加上述方法

deinit {
        NotificationCenter.default.removeObserver(self)
}

REF:在哪里删除 Swift 中 NSNotification 的观察者?

更新:

检查你的类实例是否已经存在,即当你实例化这个视图控制器时你可以这样做

if let vc = yourNotificationViewCointrollerObj {
    // USE EXISTING ONE
} else {
    // CREATE NEW INSTANCE
}
于 2018-03-10T08:03:36.703 回答