我有一個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
內部方法。