我正在开发一个带有 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];
}
这很好用。我有一张 table ,里面有一些虚拟内容。但是当我添加此代码时:
-(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]];
但是效果很好。
这里出了什么问题?
最佳答案
您需要保留testList
。 tableView:numberOfRowsInSection:
中的以下行不保留它:
testList = [dirContents filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"self ENDSWITH '.stest'"]];
filteredArrayUsingPredicate
返回您不拥有的对象(根据对象所有权策略)。由于您直接访问 ivar testList
,因此您需要通过向其发送保留消息来声明该对象的所有权(并在将来的某个时刻释放它)。
请注意,testList = ...
和 self.testList = ...
不同。前者直接访问 ivar,而后者则通过属性 testList
的访问器(如果有的话)。因此,如果您有一个 testList
保留属性,它就像这样简单:
self.testList = [dirContents filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"self ENDSWITH '.stest'"]];
如果您没有有testList
保留属性,您可以像这样保留该对象:
testList = [[dirContents filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"self ENDSWITH '.stest'"]] retain];
我鼓励您使用属性,因为它们封装了内存管理代码,从而减少了样板代码。
关于ios - didSelectRowAtIndexPath 中的 NSIndexPath 和 objectAtIndex 崩溃?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6562952/