didSelectRowAtIndexPath 中的 NSIndexPath 和 objectAtIndex 崩溃?

发布于 2024-11-18 00:54:50 字数 2241 浏览 5 评论 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]];

但是效果很好。

这里出了什么问题?

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

瞄了个咪的 2024-11-25 00:54:50

您需要保留testListtableView: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];

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

You need to retain testList. The following line in tableView:numberOfRowsInSection: does not retain it:

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

filteredArrayUsingPredicate returns an object you do not own (according to the Object Ownership Policy). Since you are accesing the ivar testList 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 = ... and self.testList = ... are not the same. The former accesses the ivar directly while the later goes through the accessor of the property testList (if you have one). So, if you have a testList retain property, it is as simple as this:

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

If you do not have a testList retain property, you can retain the object like this:

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

I encourage you to use a property since they encapsulate memory management code and thus reduce boilerplate code.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文