Использование NSPredicate для фильтрации массива вызвало exc_bad_access со второй попытки - PullRequest
0 голосов
/ 22 февраля 2012

Я использую следующий код для заполнения UITableViewController

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    NSString *selectedWord;

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

    ResultDetail *detail = [[[GameStore defaultStore] currentResultDetail] objectAtIndex:[indexPath row]];

    if([[detail selectedWord] isEqualToString:@"  "])
    {
        selectedWord = @" selected: n/a";
    }
    else{
        selectedWord = [NSString stringWithFormat:@" selected: %@", [[detail selectedWord] substringFromIndex:4]];
    }
    [[cell textLabel] setText:[NSString stringWithFormat:@" %@ (score: %d/4)",[detail word],[detail score]]];
    [[cell detailTextLabel] setText:selectedWord];

    detail = nil;
    [detail release];
    selectedWord = nil;
    [selectedWord release];

    return cell;
}

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

Вот код для currentResultDetail

- (NSArray *) currentResultDetail {

    NSLog(@"predicate: resultid == %d", [[GameStore defaultStore] currentResultId]);
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"resultId == %d", [[GameStore defaultStore] currentResultId] ];
    NSArray *filtered  = [[[GameStore defaultStore] allResults] filteredArrayUsingPredicate:predicate]; // failed here but only if currentResultId has been requested before. 

    predicate = nil;
    [predicate release];
    return [[filtered objectAtIndex:0] resultDetails];
}

Код выше приведен в следующей строке:

NSArray *filtered  = [[[GameStore defaultStore] allResults] filteredArrayUsingPredicate:predicate];

Так что, в принципе, если пользователь запрашивает currentResultDetail для currentResultId 1,2,3,4,5,6,7 в этом порядке, он работает нормально.Но если они запросят 1,2,3,4,5,1, он будет аварийно завершен.

Любой указатель на то, почему это происходит?

1 Ответ

2 голосов
/ 22 февраля 2012

Ваш предикат возвращается авто-релизом. Не выпускайте его вручную, иначе произойдет сбой, когда автозапуск попытается его освободить.

...