2014-02-13 34 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,它會從商店中刪除該事件。進行此更改後,該應用不再崩潰。