我正在使用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
中添加了删除观察者,但它甚至没有调用。如何多次停止呼叫。
答案 0 :(得分: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);
}
答案 1 :(得分: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)
}
参考:Where to remove observer for NSNotification in Swift?
更新:
检查类实例是否已经存在,即 在您实例化此视图控制器时查看 你可以这样做
if let vc = yourNotificationViewCointrollerObj {
// USE EXISTING ONE
} else {
// CREATE NEW INSTANCE
}
答案 2 :(得分: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)
}
这是你在收到一份你不喜欢的报纸试验后在现实世界中所做的事情:)