我有一个带有自定义插件的Cordova应用程序,该插件在用户的iCloud日历中创建和更新EKEvents。
我正在使用以下函数根据其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
内部方法。< / p>
答案 0 :(得分:1)
对于它的价值,我无法弄清楚修改事件的问题是什么,所以我改为删除事件(如果存在)并创建一个新事件。我的getEventWithURL
方法现在称为deleteEventWithURL
,它会从商店中删除事件。该应用程序在进行此更改后不再崩溃。