代码之家  ›  专栏  ›  技术社区  ›  Rob Lourens

设置cell.imageview.image时的objc_msgsend

  •  0
  • Rob Lourens  · 技术社区  · 16 年前

    在我开始滚动之前,此代码工作正常:

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    
    static NSString *CellIdentifier = @"cell";
    
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
        cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
    }
    
    Route *r = [data routeForDay:day index:indexPath.row];
    cell.textLabel.text = r.name;
    cell.imageView.image = r.image;
    
    return cell;
    }
    

    它对每一行都非常有效,直到我向下滚动,当它与cell.imageview.image=r.image上的objc_msgsend一起崩溃时;我已经确认没有任何内容是空的,我甚至检查了所有相关内容的重新登录。我完全不知所措,知道吗?谢谢。

    编辑:

    我解决了这个问题,但不明白代码的更改是如何使bug消失的,所以如果有人知道的话,我会很感激你的提示。

    这是最初在route init方法中创建映像的方式。当在我的tableview控制器中滚动表时,图像被解除分配。

    NSString *imagePath = [[NSBundle mainBundle] pathForResource:[dict valueForKey:@"image"] ofType:@"png"];
    image = [UIImage imageWithContentsOfFile:imagePath];
    

    当我把第二行改成

    image = [[UIImage alloc] initWithContentsOfFile:imagePath];
    

    它工作得很好。

    我只是有点困惑和不开心。

    1 回复  |  直到 16 年前
        1
  •  3
  •   Nikolai Ruhe    16 年前

    你的bug绝对是一个保留/释放问题。试着打开僵尸。如果你不知道怎么做,请看下面的内容 this tech note

    我假设其中一个物体指向 data , r r.image 未正确保留。

    还有一件事:别看 retainCount 在深入了解内存管理(尤其是自动释放池)之前。否则你只会被返回的值搞糊涂。

    如何启用僵尸:

    选择“项目”>“编辑活动可执行文件”以打开“可执行文件信息”窗口。
    单击“参数”。
    单击“要在环境中设置的变量”部分中的“添加”(+)按钮。
    在“名称”列中输入nszombieenabled,在“值”列中输入yes。
    确保选中了nszombieenabled项的复选标记。

    编辑:

    恭喜你找到了虫子。你唯一还没有找到的谜题是理解cocoas的内存管理。我建议你读 the official documentation ,因为它简洁易读。

    简而言之: imageWithContentsOfFile: 返回自动释放的对象,而 initWithContentsOfFile: 返回保留的对象。但是,请再次阅读文档,否则您将继续出现内存错误。