Как ограничить NSNotification для вызова методов несколько раз в iOS?
Я использую NSNotificationCenter
отправлять локальные уведомления в моем коде и работать как в Objective-C и Swift. Я выкладываю уведомления от Objective-C и получаю в Swift. Но методы, которые я добавил в уведомление, вызывались несколько раз, а наблюдатель добавлялся только в viewDidLoad
метод.
Swift:
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);
}
Objective-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
но это даже не зовет. Как перестать звонить несколько раз.
3 ответа
Ты можешь сделать это
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: Где убрать наблюдателя для NSNotification в Swift?
Обновить:
Проверьте свой экземпляр класса, если он уже существует, то есть, когда вы создаете экземпляр этого контроллера представления, вы можете сделать это следующим образом
if let vc = yourNotificationViewCointrollerObj {
// USE EXISTING ONE
} else {
// CREATE NEW INSTANCE
}
//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);
}
NSNotificationCenter - это механизм "публикация-подписка", при котором каждое опубликованное уведомление доставляется всем подписчикам (так называемым наблюдателям). Если вы получаете уведомление несколько раз, это означает, что у вас есть несколько подписчиков или вы отправляете уведомление несколько раз.
Я предполагаю, что у вас есть только один подписчик для каждого типа уведомлений - ваш MainScreen UIViewController в Swift. Это означает, что вы, вероятно, отправляете каждое уведомление несколько раз.
Например 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)
}
Это то, что вы делаете в реальном мире после получения газеты, которая вам не понравилась:)