1

I'm trying to fetch EKEvents from the Event Store to populate a UITableView and display a month list view.

Basically it works and I'm doing it like this:

- (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 is called from within a

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void)
{
    [self reloadEvents];
});

as fetching events happens synchronously and it locks the UI for that time, I'm using GCD. The NSDate parts are my own categories on NSDate.

Now, when my view controller loads, events are fetched from the Event Store and displayed correctly. The view controller also listens for EKEventStoreChangedNotification and that's where my app crashes. When I change an event outside my app it receives a notification and tries to reload the event data, but then...

*** -[CFString length]: message sent to deallocated instance 0x666f530

EDIT I've changed reloadEvents to the following:

- (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];
                   });
}

and with this, the app doesn't crash anymore. Seems like something changed calendarA and therefore the entry was already deallocated (which, after having found the cause of the problem, is absolutely logical).

jscs
  • 63,694
  • 13
  • 151
  • 195
  • 1
    I don't see any issues with code you've posted. I see you have set environment variable NSZombieEnabled to YES, check this SO question http://stackoverflow.com/questions/7940198/exc-bad-access-message-sent-to-deallocated-instance-but-im-using-arc/7940254#7940254, look for chown user's answer and try debugging . If possible can you create a small project with this code (that crashes) and post it here. – 0x8badf00d Nov 01 '11 at 18:12
  • Is it possible that something running in another thread is changing calendarA? That would mess up the enumeration. – Flyingdiver Nov 01 '11 at 18:16
  • 1
    There's not enough code here to diagnose. – James Nov 01 '11 at 18:46
  • I guess @Flyingdiver was right. Something did change my array in the meantime, which messed up the enumeration. After changing the code a bit, it now works as expected. Thanks you very much!!! – Martin Hasenbein Nov 01 '11 at 19:09
  • 1
    It would be helpful if you could write that comment up as an answer and then accept it. – bearMountain Jan 17 '12 at 18:41

0 Answers0