NSIndexPath и objectAtIndex в didSelectRowAtIndexPath аварийно завершают работу? - PullRequest
0 голосов
/ 03 июля 2011

Я работаю над небольшим проектом iOS с UITableView.

Я создал таблицу и поместил в нее некоторый контент:

-(void)configureCell:(UITableViewCell *)cell forIndexPath:(NSIndexPath *)indexPath {
    NSString *fileName = [testList objectAtIndex:[indexPath row]];
    NSString *docsDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    NSString *testPath = [docsDir stringByAppendingPathComponent:fileName];


    NSMutableDictionary *plistDict = [NSMutableDictionary dictionaryWithContentsOfFile:testPath];
    [[cell textLabel] setText:[plistDict valueForKey:@"title"]];
}
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"indentifier"];
    if(cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"identifier"];
        [cell autorelease];
    }

    [self configureCell:cell forIndexPath:indexPath];

    return cell;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    NSString *docsDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    NSArray *dirContents = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:docsDir error:nil];
    testList = [dirContents filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"self ENDSWITH '.stest'"]];
    return [testList count];
}

Это прекрасно работает.У меня есть таблица с каким-то фиктивным содержанием.Но когда я добавляю этот код:

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    [testTable deselectRowAtIndexPath:indexPath animated:YES];
    NSLog(@"%d",[indexPath row]);
    NSLog(@"%@",[testList objectAtIndex:[indexPath row]]);
}

Симулятор iOS падает (он не завершается, но приложение больше не отвечает), когда я нажимаю ячейку в таблице.Причиной этого является следующая строка:

 NSLog(@"%@",[testList objectAtIndex:[indexPath row]]);

Когда я удаляю эту строку, она отлично работает.Этот журнал:

NSLog(@"%d",[indexPath row]);

Возвращает номер строки, как обычно.

Странно то, что я делаю то же самое в функции configureCell:

NSString *fileName = [testList objectAtIndex:[indexPath row]];

Но это прекрасно работает.

Что здесь не так?

1 Ответ

1 голос
/ 03 июля 2011

Вам необходимо сохранить testList.Следующая строка в tableView:numberOfRowsInSection: не не сохраняет его:

testList = [dirContents filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"self ENDSWITH '.stest'"]];

filteredArrayUsingPredicate возвращает объект, который вы не владеете (в соответствии с политикой владения объектом).Поскольку вы обращаетесь к ivar testList напрямую, вам необходимо подтвердить право собственности на объект, отправив ему сообщение сохранения (и отпустите его в какой-то момент в будущем).

Обратите внимание, что testList = ... и self.testList = ... не одинаковы.Первый получает доступ к ивару напрямую, а второй - через средство доступа к свойству testList (если оно есть).Итак, если у вас есть свойство testList retain, это так просто:

self.testList = [dirContents filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"self ENDSWITH '.stest'"]];

Если у вас нет есть свойство testList, вы можете сохранитьобъект, подобный этому:

testList = [[dirContents filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"self ENDSWITH '.stest'"]] retain];

Я рекомендую вам использовать свойство, так как они инкапсулируют код управления памятью и таким образом сокращают стандартный код.

...