0

我正在开发一个带有 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]];

但这很好用。

这里出了什么问题?

4

1 回答 1

1

您需要保留testList. 以下行tableView:numberOfRowsInSection:保留它:

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

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

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

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

如果您没有testList保留属性,则可以像这样保留对象:

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

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

于 2011-07-03T12:56:26.117 回答