Objective c ref计数的一个不太明显的递减

Objective c ref计数的一个不太明显的递减,objective-c,Objective C,Xcode Analyze抱怨我在标记为“this line”的行错误地减少了ref计数。这似乎有点奇怪,因为这条线是否会减少ref计数并不明显 - (void)connectionDidFinishLoading:(NSURLConnection *)connection { UIImage * image = [[UIImage alloc] initWithData:receivedData]; if (image == nil) { image = [UI

Xcode Analyze抱怨我在标记为“this line”的行错误地减少了ref计数。这似乎有点奇怪,因为这条线是否会减少ref计数并不明显

- (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];
}

我不是Objective-C专家,但似乎您正在用本地指针图像覆盖sefl.itemImage.image的内容,因此减少了对self.itemImage.image中存储的内容的引用


我认为本地映像为null或非null与此无关

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

查看
if
会导致
图像
包含代码不拥有的对象

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
的评论,这样八个月后你就会记得你为什么这么做了


比这更好,正如下面所建议的,你自己已经明白了,那就是自动地去修改<代码> OLC/<代码>图像,除去后面的代码>发布<代码> > .P/>我相信Josh主要得到了这个,但是我会澄清……/P>

[UIImage imageNamed:@"null.bmp"];
这将创建一个自动释放UIImage

但是

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

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

不确定为什么其他人删除了他们的回复,但在他们删除之前我已经阅读了。是的,我明白了重点,解决方案是删除发布声明,并修改第一行-这样它是一致的,无论是否执行if块,我都不拥有映像。谢谢大家!我的回答又回来了——我那喝咖啡的脑袋让我回想过去,在我感到尴尬之前,我不得不修改一下。很高兴我能帮上忙。或者自动释放
-initWith…
图像并放下
-release
@bavariable:没错!事实上,我认为这是彼得佩果已经选择的解决方案,根据问题所附的评论。