我有一个Cordova应用程序,其中包含一个定制插件,用于在用户的iCloud日历中创建和更新EKEvents。更新EKEvent时收到间歇性EXC_BAD_ACCESS
我使用下面的函数基于其URL找到特定EKEvent:
- (EKEvent*) getEventWithURL:(NSString *)pstrURL store:(EKEventStore *)pStore
{
EKCalendar* calendar = [self getCalendarByName:mstrCalendarName store:pStore createIfDoesNotExist:false];
NSArray* calendars = [[NSArray alloc] initWithObjects: calendar, nil];
NSDateFormatter *sDate = [[NSDateFormatter alloc] init];
[sDate setDateFormat:@"yyyy-MM-dd HH:mm"];
NSDate *myStartDate = [sDate dateFromString:@"2013-11-01 00:00"];
NSDateFormatter *eDate = [[NSDateFormatter alloc] init];
[eDate setDateFormat:@"yyyy-MM-dd HH:mm"];
NSDate *myEndDate = [eDate dateFromString:@"2014-12-31 23:59"];
NSPredicate *predicate = [pStore predicateForEventsWithStartDate:myStartDate endDate:myEndDate calendars: calendars];
// Fetch all events that match the predicate.
NSArray *events = [pStore eventsMatchingPredicate:predicate];
EKEvent *foundEvent = nil;
EKEvent *event;
for (id oEvent in events)
{
event = (EKEvent *)oEvent;
if ([event.URL isEqual:[NSURL URLWithString:pstrURL]])
{
foundEvent = event;
break;
}
}
return foundEvent;
}
它,然后修改(开始和结束日期更改),并保存在另一种方法用下面的代码:
EKEvent *myEvent = nil;
BOOL saved = false;
EKCalendar* calendar = nil;
if(pstrCalendarTitle == nil)
{
calendar = pStore.defaultCalendarForNewEvents;
}
else
{
calendar = [self getCalendarByName: pstrCalendarTitle store: pStore createIfDoesNotExist:true];
}
// find event if it exists
myEvent = [self getEventWithURL:[NSString stringWithFormat: @"custom://%@", pstrTSDID ] store:pStore];
// if an event wasn't found, create a new one
if (myEvent == nil)
{
myEvent = [EKEvent eventWithEventStore: pStore];
}
// set all the fields to new values
myEvent.title = pstrTitle;
myEvent.location = pstrLocation;
myEvent.notes = pstrMessage;
myEvent.startDate = pdtStartDate;
myEvent.endDate = pdtEndDate;
myEvent.calendar = calendar;
myEvent.URL = [NSURL URLWithString:[NSString stringWithFormat: @"custom://%@", pstrTSDID ]];
// only add an alarm if one hasn't been created already
if ([[myEvent alarms] count] == 0)
{
EKAlarm *reminder = [EKAlarm alarmWithRelativeOffset:-2*60*60];
[myEvent addAlarm:reminder];
}
当更新事件时产生EKEvents的一大堆(连续约30)我没有得到EXC_BAD_ACCESS
错误,但是我得到的EXC_BAD_ACCESS
错误间歇。有时它是第一次更新,有时我能够在看到错误之前更新10,然后崩溃我的应用程序。
我怀疑它可能与foundEvent变量没有被保留有关,但是我的项目使用ARC,所以我理解我不需要执行任何内存管理任务。除非ARC与事件变量被施放的方式混淆,然后在getEventWithURL
的循环中传递?
为了充分披露,我确实启用了Enable Zombie Objects
,并且我看到的堆栈跟踪没有特别引用我的任何方法,它从start_wqthread开始,然后引用一些EKEventStore _databasechangedexternally
内部方法。