didSelectRowAtIndexPath中的NSIndexPath和objectAtIndex崩溃了吗?

时间:2011-07-03 12:44:53

标签: ios uitableview nsindexpath

我正在开发一个带有UITableView的小型iOS项目。

我制作了一张桌子,并在其中加入了一些内容:

-(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 个答案:

答案 0 :(得分:1)

您需要保留testListtableView:numberOfRowsInSection:中的以下行保留它:

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

filteredArrayUsingPredicate会返回您拥有的对象(根据对象所有权政策)。由于您直接访问ivar testList,因此您需要通过向对象发送保留消息来声明该对象的所有权(并在将来的某个时间将其释放)。

请注意,testList = ...self.testList = ...不一样。前者直接访问ivar,而后者则通过属性testList的访问者(如果有的话)。所以,如果你有一个testList retain属性,它就像这样简单:

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

如果您拥有testList保留属性,则可以保留此对象:

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

我鼓励您使用属性,因为它们封装了内存管理代码,从而减少了样板代码。