EKEvent
イベント ストアからをフェッチしUITableView
て、月のリスト ビューを設定して表示しようとしています。
基本的にそれは機能し、私は次のようにしています:
- (void) reloadEvents
{
for ( NSString *entry in self.calendarA )
{
NSMutableArray *tempArray = [[[NSMutableArray alloc] init] autorelease];
[tempArray addObjectsFromArray:[appDelegate.eventStore eventsMatchingPredicate:[appDelegate.eventStore predicateForEventsWithStartDate:[NSDate fromString:entry] endDate:[[NSDate fromString:entry] midnight] calendars:nil]]];
[tempArray addObjectsFromArray:[self initializeItems:[NSDate fromString:entry] withEndDate:[[NSDate fromString:entry] midnight]]];
[tempArray sortUsingDescriptors:[NSArray arrayWithObject:[[[NSSortDescriptor alloc] initWithKey:@"startDate" ascending:YES] autorelease]]];
[[self.calendarD objectForKey:entry] addObjectsFromArray:tempArray];
}
dispatch_async(dispatch_get_main_queue(), ^(void)
{
[self redrawTableCells];
});
}
reloadEvents
内から呼び出されます
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void)
{
[self reloadEvents];
});
イベントの取得は同期的に行われ、その間 UI がロックされるため、GCD を使用しています。パーツはのNSDate
私自身のカテゴリNSDate
です。
これで、ビュー コントローラーが読み込まれると、イベント ストアからイベントが取得され、正しく表示されるようになりました。ビューコントローラーもリッスンしEKEventStoreChangedNotification
、そこでアプリがクラッシュします。アプリの外部でイベントを変更すると、通知を受け取り、イベント データをリロードしようとしますが、その後...
*** -[CFString length]:
割り当て解除されたインスタンス 0x666f530 に送信されたメッセージ
編集
私はreloadEvents
次のように変更しました:
- (void) reloadEvents
{
NSArray *daysArray = [[self.calendarD allKeys] sortedArrayUsingSelector:@selector(compare:)];
for ( NSString *entry in daysArray )
{
NSMutableArray *tempArray = [[NSMutableArray alloc] init];
[tempArray addObjectsFromArray:[appDelegate.eventStore eventsMatchingPredicate:[appDelegate.eventStore predicateForEventsWithStartDate:[NSDate fromString:entry] endDate:[[NSDate fromString:entry] midnight] calendars:nil]]];
[tempArray addObjectsFromArray:[self initializeItems:[NSDate fromString:entry] withEndDate:[[NSDate fromString:entry] midnight]]];
[tempArray sortUsingDescriptors:[NSArray arrayWithObject:[[[NSSortDescriptor alloc] initWithKey:@"startDate" ascending:YES] autorelease]]];
[[self.calendarD objectForKey:entry] addObjectsFromArray:tempArray];
[tempArray release];
}
dispatch_async(dispatch_get_main_queue(), ^(void)
{
[self redrawTableCells];
});
}
これにより、アプリはクラッシュしなくなりました。何かが変更されたように見えるcalendarA
ため、エントリは既に割り当て解除されています (問題の原因を見つけた後、これは完全に論理的です)。