2014-02-13 29 views
0

我有一个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内部方法。

回答

1

对于它的价值,我无法弄清楚修改事件是什么问题,所以我改为删除事件(如果存在)并创建一个新事件。我的getEventWithURL方法现在被称为deleteEventWithURL,它会从商店中删除该事件。进行此更改后,该应用不再崩溃。