一个不那么明显的引用计数减少

时间:2011-10-25 23:44:58

标签: objective-c

Xcode Analyze抱怨我在标记为“此行”的行上错误地减少了引用计数。这看起来有点奇怪,因为这条线减少参考计数并不明显。

- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    UIImage * image = [[UIImage alloc] initWithData:receivedData];
    if (image == nil) {
        image = [UIImage imageNamed:@"null.bmp"];
    }
    self.itemImage.image = image; //this line
    self.promotion.image = image; 
    [image release];
}

3 个答案:

答案 0 :(得分:5)

这是一个有点棘手的事情;这是可以理解的,它引起了混乱。这里的两个路径导致image持有具有不同所有权状态的对象,从而导致不同的引用计数。

完成if会导致image持有您的代码不拥有的对象。

UIImage * image = [[UIImage alloc] initWithData:receivedData];
// If |initWithData:| succeeds, the object in |image| is owned, because you
// called |alloc| to create it.
if (image == nil) {
    image = [UIImage imageNamed:@"null.bmp"];
    // This object is _not_ owned by your code and you must not send
    // |release| to it.
}
// ... the setter lines are irrelevant to the reference count of |image|.

[image release];
// This is only okay if |initWithData:| succeeded and you have ownership
// of |image|.

我认为分析器指示错误的行,就像编译器会抱怨以后丢失分号五行一样。

解决此问题的方法可能是保留您从imageNamed:获得的图片无法不发送release,因为您在一个案例中拥有image,您需要妥善放弃该所有权。我还建议在那里发表关于发送retain的评论,以便你记得八个月之后为什么要这样做。

比这更好,正如下面由无法模仿的Bavarious所建议的,并且我认为你自己已经想到了,将自动发布alloc'd图像并删除后面的release行。< / p>

答案 1 :(得分:1)

我不是Objective-C专家,但似乎你用本地指针图像覆盖sefl.itemImage.image的内容,因此将一个ref减少到self.itemImage.image之前存储的内容。分配

我不认为本地图像为null或非null与它有关。

答案 2 :(得分:1)

我相信Josh主要得到这个,但我会澄清......

[UIImage imageNamed:@"null.bmp"];

这会创建一个自动释放UIImage。

但是...

UIImage * image = [[UIImage alloc] initWithData:receivedData];

创建一个需要显式发布的变量。因此,根据您是否收到数据(可能是网络关闭),您将拥有不同的所有权规则,具体取决于图像是分配了显式发布要求还是自动释放。因此,如果没有收到数据,[图像发布]将是不正确的。