簡體   English   中英

多次調用EKEventStoreChangedNotification

[英]EKEventStoreChangedNotification gets called several times

我在我的應用程序中使用EKEventStore。 我抓住默認商店並注冊EKEventStoreChangedNotification ,以便在對日歷進行更改時收到通知。 但是,當進行更改時,通知的發件人會被調用幾次(5-10)次,有時在每次調用之間最多會有15秒。 這會弄亂我的代碼並使事情變得更加困難。 我能做些什么嗎?

謝謝

iOS7編輯:似乎就像iOS7的發布一樣,這個問題已經消失了。 現在,無論對CalendarStore所做的更改如何,都只發送一個EKEventStoreChangedNotification

這是調度通知的確切方式以及每個實際通知的結果。 根據我的經驗,您可以期望收到至少一個項目更改通知(事件,提醒等),並至少再收到一個更改,以便對該項目的包含日歷進行更改。

如果沒有看到您的代碼並知道正在做出哪些更改,我就無法對答案過於具體; 但是,一般來說,您有兩種選擇。

  1. 更密切地觀察更改 - 如果涉及與您的應用無關的事件,或者您已經處理了特定項目的更改,則可以安全地忽略某些通知。
  2. 將多個更改合並為一批處理程序代碼。 基本上,當您收到通知時,不要立即啟動響應,而是啟動一個計時器,該計時器將在一兩秒內運行響應。 然后,如果在計時器觸發之前有另一個通知,您可以取消計時器並重置它。 這樣,您可以批量處理在短時間窗口內發出的多個通知,並且只響應一次(當計時器最終觸發時)。

后一個解決方案是我的首選答案,可能看起來像(暫時忽略線程問題):

@property (strong) NSTimer *handlerTimer;

- (void)handleNotification:(NSNotification *)note {
    // This is the function that gets called on EKEventStoreChangedNotifications
    [self.handlerTimer invalidate];
    self.handlerTimer = [NSTimer timerWithTimeInterval:2.0
                                                target:self
                                              selector:@selector(respond)
                                              userInfo:nil
                                               repeats:NO];
    [[NSRunLoop mainRunLoop] addTimer:self.handlerTimer
                              forMode:NSDefaultRunLoopMode];
}

- (void)respond {
    [self.handlerTimer invalidate];
    NSLog(@"Here's where you actually respond to the event changes");
}

我也有這個問題。 經過一些調試后,我意識到我正在引發額外的EKEventStoreChangedNotification調用(例如,通過創建或刪除EKReminder )。 EKEventStoreChangedNotification當我做一個最終被觸發estore.commit()

我通過聲明全局變量來解決這個問題:

// the estore.commit in another function causes a new EKEventStoreChangedNotification. In such cases I will set the ignoreEKEventStoreChangedNotification to true so that I DON'T trigger AGAIN some of the other actions.
var ignoreEKEventStoreChangedNotification = false 

然后在AppDelegate.swift中執行此操作,我在其中收聽EKEventStoreChangedNotification

nc.addObserver(forName: NSNotification.Name(rawValue: "EKEventStoreChangedNotification"), object: estore, queue: updateQueue) {
            notification in

        if ignoreEKEventStoreChangedNotification {
            ignoreEKEventStoreChangedNotification = false
            return
        }

        // Rest of your code here.

}

在我更改estore的函數中,我這樣做:

//
// lots of changes to estore here...
//
ignoreEKEventStoreChangedNotification = true        // the estore.commit causes a new EKEventStoreChangedNotification because I made changes. Ignore this EKEventStoreChangedNotification - I know that changes happened, I caused them!
try estore.commit()

它與全局變量不同(特別是如果你正在進行函數式編程),但它有效。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM