didSelectRowAtIndexPath 中的 NSIndexPath 和 objectAtIndex 崩溃?
我正在开发一个带有 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]];
但是效果很好。
这里出了什么问题?
I am working on a small iOS project, with a UITableView.
I made a table and put some content in it:
-(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];
}
This works fine. I have a table with some dummy content in it. But when i am adding this code:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[testTable deselectRowAtIndexPath:indexPath animated:YES];
NSLog(@"%d",[indexPath row]);
NSLog(@"%@",[testList objectAtIndex:[indexPath row]]);
}
The iOS simulator crashes(its not quiting, but the app doesn't respond anymore) when i press a cell in the table. The cause of this is the next line:
NSLog(@"%@",[testList objectAtIndex:[indexPath row]]);
When i delete this line it works perfect. This log:
NSLog(@"%d",[indexPath row]);
Returns the row number, as normal.
The strange thing is that i do exactly the same in the configureCell Function:
NSString *fileName = [testList objectAtIndex:[indexPath row]];
But that works fine.
What is going wrong here?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您需要保留
testList
。tableView:numberOfRowsInSection:
中的以下行不保留它:filteredArrayUsingPredicate
返回一个您不拥有的对象(根据对象所有权策略)。由于您直接访问 ivartestList
,因此需要通过向对象发送保留消息来声明对象的所有权(并在将来的某个时刻释放它)。请注意,
testList = ...
和self.testList = ...
并不相同。前者直接访问 ivar,而后者则通过属性testList
的访问器(如果有的话)。因此,如果您有一个testList
保留属性,那么就这么简单:如果您没有有一个
testList
保留属性,您可以像这样保留对象:我鼓励您使用属性,因为它们封装了内存管理代码,从而减少了样板代码。
You need to retain
testList
. The following line intableView:numberOfRowsInSection:
does not retain it:filteredArrayUsingPredicate
returns an object you do not own (according to the Object Ownership Policy). Since you are accesing the ivartestList
directly, you need to claim ownership of the object by sending it a retain message (and release it at some point in the future).Note that
testList = ...
andself.testList = ...
are not the same. The former accesses the ivar directly while the later goes through the accessor of the propertytestList
(if you have one). So, if you have atestList
retain property, it is as simple as this:If you do not have a
testList
retain property, you can retain the object like this:I encourage you to use a property since they encapsulate memory management code and thus reduce boilerplate code.