更新EKEvent时接收间歇性EXC_BAD_ACCESS

时间:2014-02-13 20:16:21

标签: ios objective-c exc-bad-access

我有一个带有自定义插件的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>

1 个答案:

答案 0 :(得分:1)

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