Календари в массиве выходят за рамки после фильтрации

Я делаю небольшую программу, которая будет помещать некоторые события в календарь на iPhone. В настройках я позволю пользователю выбрать, какой календарь использовать. Чтобы показать, какие календари он может использовать, я извлекаю все календари из EKEventStore и отбираю те, в которые нельзя вносить изменения. На них подписаны с других сайтов.

После фильтра, с которым вроде бы все в порядке, массив уменьшается с 5 до 3 календарей, все объекты в массиве выходят за рамки, а список в табличном представлении пуст.

Что мне не хватает?

Изменить: проблема возникла, когда я начал с фильтрации, поэтому я подумал, что это проблема, но теперь кажется, что объекты выходят за рамки, когда -(NSArray*) availableCalendar возвращает массив. Мне нужно скопировать его или что-то в этом роде?

Изображение здесь: http://d.pr/35HY

-(NSArray*)availableCalendars{
    NSArray *calendars;
    EKEventStore *eventDB = [[[EKEventStore alloc]init]autorelease];
    calendars = [[[NSArray alloc]initWithArray:[eventDB calendars]]autorelease];

    return calendars;
}

- (void)viewDidLoad {
    [super viewDidLoad];

    allcalendars = [self availableCalendars];
    [allcalendars retain];

    localCalendars = [[NSMutableArray alloc]initWithArray:allcalendars];


    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"allowsContentModifications == YES"];
    [localCalendars filterUsingPredicate:predicate];

    calendarCountInt = localCalendars.count; //When I break the code here, the three objects are 'Out of Scope' and the count is three
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{

    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    }

    if (calendarCountInt > 0)
    {
        cell.textLabel.text = [[localCalendars objectAtIndex:indexPath.row] title] ;
    }
    else {
        cell.textLabel.text = @"No Calendars found";
    }


    return cell;
}

- (void)dealloc {
    [localCalendars release];
    [allcalendars release];
    [super dealloc]; 
}

person Cub71    schedule 21.02.2011    source источник
comment
То, что отладчик сообщает вам, что что-то выходит за рамки, не означает, что с вашим кодом что-то не так. GDB временами довольно глуп и не очень хорошо понимает Obj-C (по крайней мере, это мой опыт).   -  person Ole Begemann    schedule 21.02.2011
comment
Что ж, в этом случае GDB кажется правым. TableView пуст. Проблема заключается в преобразовании из массива в mutalbleArray. Этот вызов создает проблему: [localCalendars addObjectsFromArray:theseCalendars]; где localCalendars — это массив NSMutablearray, а эти календари — это NSArray.   -  person Cub71    schedule 21.02.2011


Ответы (1)


Ваш код... интересен. Я предполагаю, что вы делаете return calendarCountInt; в своем методе tableView:numberOfRowsInSection:. Если да, то это будет return 0;, когда нет календарей, допускающих изменение, что приведет к пустой таблице.

Вот как бы я это сделал:

// this requires an @property(nonatomic, retain) NSArray *allCalendars
// with a corresponding NSArray *allCalendars ivar

// also, an @property(nonatomic, retain) NSArray *localCalendars
// with a corresponding NSArray *localCalendars ivar

// get all calendars and cache them in an ivar (if necessary)
- (NSArray *)allCalendars {
    if (allCalendars == nil) {
        EKEventStore *eventDB = [[[EKEventStore alloc] init] autorelease];
        [self setAllCalendars:[eventDB calendars]];
    }
    return allCalendars;
}

// get all modifiable calendars and cache them in an ivar (if necessary)
- (NSArray *)localCalendars {
    if (localCalendars == nil) {
        NSPredicate *filter = [NSPredicate predicateWithFormat:@"allowsContentModifications == YES"];
        [self setLocalCalendars:[[self allCalendars] filteredArrayUsingPredicate:filter]];
    }
    return localCalendars;
}

// there's only one section
- (NSUInteger)numberOfSectionsInTableView:(UITableView *)aTableView {
    return 1;
}

// show the number of modifiable calendars, or 1 (if there are no modifiable calendars)
- (NSUInteger)tableView:(UITableView *)aTableView numberOfRowsInSection:(NSUInteger)section {
    NSArray *local = [self localCalendars];
    return ([local count] > 0) ? [local count] : 1;
}

// set up the cell
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    }

    if ([[self localCalendars] count] > 0) {
        cell.textLabel.text = [[[self localCalendars] objectAtIndex:[indexPath row]] title];
    }  else {
        cell.textLabel.text = @"No calendars found";
    }
}

- (void)dealloc {
    [localCalendars release], localCalendars = nil;
    [allCalendars release], allCalendars = nil;
    [super dealloc]; 
}
person Dave DeLong    schedule 21.02.2011
comment
Большое спасибо, это сработало очень хорошо. Я думаю, что правильное использование свойств помогло, а не преобразование NSArray в NSMutableArray. - person Cub71; 22.02.2011