8

我在我的应用程序中使用 EKEventStore。我获取默认存储并注册以便在EKEventStoreChangedNotification对日历进行更改时收到通知。但是,当进行更改时,通知的发送者会被调用数次 (5-10) 次,有时每次调用之间的间隔长达 15 秒。这弄乱了我的代码,使事情变得更加难以处理。对此我能做些什么吗?

谢谢

iOS7 编辑:似乎在 iOS7 发布时,这个问题已经消失了。现在,无论对 CalendarStore 所做的更改如何,都只会EKEventStoreChangedNotification发送一个。

4

2 回答 2

17

这是通知的确切发送方式以及每个通知实际通知的内容的结果。以我的经验,您可以期望收到至少一个通知,用于更改项目(事件、提醒等),并且至少收到一个通知,以更改该项目的包含日历。

在没有看到您的代码并且不知道正在进行哪些更改的情况下,我不能对答案太具体;但是,一般来说,您有两种选择。

  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");
}
于 2012-08-30T21:22:20.100 回答
0

我也有这个问题。经过一些调试后,我意识到我导致了额外的EKEventStoreChangedNotification调用(例如,通过创建或删除EKReminders)。当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()

全局变量并不漂亮(特别是如果您从事函数式编程),但它确实有效。

于 2018-09-03T16:02:24.343 回答