EKEventStore 导致 SpringBoard 崩溃

Posted

技术标签:

【中文标题】EKEventStore 导致 SpringBoard 崩溃【英文标题】:EKEventStore causes SpringBoard crash 【发布时间】:2014-04-14 10:01:24 【问题描述】:

我构建了一个从日历中获取 ekevents 的应用程序(通过 EKEventStore predicateForEventsWithStartDate:endDate:calendars:)并将应用程序事件与日历同步(通过EKEventStore saveEvent:span:commit:error:)。

我使用对EKEventStore 的静态引用,并确保我的不同进程不会同时访问EKEventStore

应用程序有时会因 ios7 上的 Springboard 崩溃而终止。这是崩溃的回溯。

Last Exception Backtrace:
0   CoreFoundation                  0x18625e950 __exceptionPreprocess + 132
1   libobjc.A.dylib                 0x1927641fc objc_exception_throw + 60
2   CoreFoundation                  0x18625e810 +[NSException raise:format:arguments:] +     116
3   Foundation                      0x186d96db4 -[NSAssertionHandler     handleFailureInMethod:object:file:lineNumber:description:] + 112
4   EventKit                        0x186adab84 -[EKEventStore _addFetchedObjectWithID:] + 240
5   EventKit                        0x186adaa64 __78-[EKEventStore registerFetchedObjectWithID:withDefaultLoadedProperties:inSet:]_block_invoke + 96
6   libdispatch.dylib               0x192d3bfd4 _dispatch_client_callout + 16
7   libdispatch.dylib               0x192d41c84 _dispatch_barrier_sync_f_invoke + 48
8   EventKit                        0x186ada990 -[EKEventStore     registerFetchedObjectWithID:withDefaultLoadedProperties:inSet:] + 148
9   EventKit                        0x186ae1458 __41-[EKPredicateSearch startWithCompletion:]_block_invoke + 796
10  EventKit                        0x186ae1050 -[EKDaemonConnection _processReplyWithID:data:finished:] + 220
11  EventKit                        0x186ae0f5c CADReceiveReply + 136
12  EventKit                        0x186ae0eac _XReply + 124
13  EventKit                        0x186ae0e04 ClientCallbacks_server + 100
14  libdispatch.dylib               0x192d3fae8 dispatch_mig_server + 352
15  EventKit                        0x186ae0d6c __43-[EKDaemonConnection initWithOptions:path:]_block_invoke16 + 44
16  libdispatch.dylib               0x192d3bfd4 _dispatch_client_callout + 16
17  libdispatch.dylib               0x192d3db90 _dispatch_source_invoke + 500
18  libdispatch.dylib               0x192d430f4 _dispatch_root_queue_drain + 104
19  libdispatch.dylib               0x192d434fc _dispatch_worker_thread2 + 76
20  libsystem_pthread.dylib         0x192ed16bc _pthread_wqthread + 356
21  libsystem_pthread.dylib         0x192ed154c start_wqthread + 4

这是我初始化 ekeventstore 的代码:

+ (EKEventStore *) sharedStore 
     static EKEventStore *sharedEventStore;

    if (sharedEventStore == nil) 
        sharedEventStore = [[EKEventStore alloc] init];
        [sharedEventStore requestAccessToEntityType: EKEntityTypeEvent completion:^(BOOL granted, NSError *error) 
        ];
        [sharedEventStore reset];
    

    return sharedEventStore;

获取事件的代码:

NSPredicate *predicate = [[CalendarHelper sharedStore] predicateForEventsWithStartDate:startDate
                                                        endDate:endDate
                                                      calendars:[[showableCalendars copy] autorelease]];
NSArray *result = [[CalendarHelper sharedStore] eventsMatchingPredicate:predicate];

并更新/创建事件:

EKEvent *event = [[CalendarHelper sharedStore] eventWithIdentifier:eventId];
if(event != nil) 
    event.title = title;
    event.startDate = startDate;
    event.endDate = endDate;
    NSLog(@"Updating...");
    NSLog(@"+++ %@", event.eventIdentifier);

    [[CalendarHelper sharedStore] saveEvent:event span:EKSpanThisEvent commit:commit error:nil];
    NSLog(@"Updated.");

else 
    NSLog(@"No event, no update");

有什么线索吗?

【问题讨论】:

你用了什么代码?你有没有先问权限? requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error) 谢谢克里斯,是的,我先询问了权限,我在上面编辑了查询以包含代码 sn-ps。 应用何时终止?您是否已经使用断点来查明问题? 应用程序通常会在保存一堆事件后几分钟(即 1 秒)终止;有时,即使将应用程序置于后台,它也会崩溃;断点似乎不是调查的解决方案,因为崩溃很难重现(大约几十次中的一次)...... 【参考方案1】:

请检查您的 ios 版本。我在使用 iOS 7.0.2 时遇到了类似的崩溃,如果不尝试以下代码

似乎这个错误的原因与我们试图在我们的应用程序中获取多少事件有关。检查苹果的错误报告 (15424747)。

当我们的应用确实在具有大范围日期的 eventStore 上进行谓词时,似乎会引入此错误。

代码如下:

NSPredicate *predicate = [self.eventStore predicateForEventsWithStartDate:startDate     endDate:endDate calendars:nil]; 

//我们使用NSSortDescriptor进行排序

if (!self.masterListSortDescriptor)
    
    self.masterListSortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"startDate"  ascending:YES]; 


NSArray *result = [[self.eventStore eventsMatchingPredicate:predicate]
sortedArrayUsingDescriptors:@[self.masterListSortDescriptor]];

【讨论】:

我的应用程序的谓词范围为 2 周,您认为这会导致崩溃吗(我有类似的崩溃描述)

以上是关于EKEventStore 导致 SpringBoard 崩溃的主要内容,如果未能解决你的问题,请参考以下文章

应用程序关闭时如何在 EKEventStore 中检测?

EKEventStore 不会按外部或本地标识符返回 Exchange 日历项目

在 EKEventStore 中检索具有特定标题的 EKEvent

EKEventstore 和唯一的日历标识符

EKEventStore removeEvent EKErrorDomain 代码=11 EKErrorObjectBelongsToDifferentStore

无法在 macOS 的 Swift 应用程序中请求日历事件访问(通过 EKEventStore)