【问题标题】:initWithContentsOfFile:path] memory management when returns nilinitWithContentsOfFile:path] 返回 nil 时的内存管理
【发布时间】:2011-09-28 16:15:59
【问题描述】:

[[UIImage alloc] initWithContentsOfFile:path]

当方法无法初始化图像时返回 nil。然后下一个代码不会释放分配的 UIImage,因为图像在 [image release] 行中为零:

UIImage* image = [[UIImage alloc] initWithContentsOfFile:path];
if(image)
{
....
}
//Here image is nil and not releases allocated UIImage.
[image release];

这真的是内存泄漏吗?

如果 init 返回 nil,必须如何释放对象? 如果我做 UIImage* image = [[UIImage alloc] initWithContentsOfFile:path];

并且图像为零,因为初始化失败, [image release] 与 [nil release] 相同。好的,没有错误,但没有发布任何内容。

【问题讨论】:

    标签: iphone uiimage release alloc


    【解决方案1】:

    此示例中的保留计数与图像是否为零无关。您使用

    手动分配图像
    UIImage* test = [UIImage alloc];
    

    因此,在您手动释放它之前,保留计数将为 1,因为您是该对象的唯一所有者。

    有关该主题的更多信息,请参阅Memory Management Rules

    【讨论】:

    • 是的,但是如果 init 返回 nil,必须如何释放对象?如果我做 UIImage* image = [[UIImage alloc] initWithContentsOfFile:path];并且image为nil,[image release]与[nil release]相同,不释放分配的对象
    • 你不需要释放它,因为它是 nil,尽管调用 [image release] 并没有什么坏处,因为图像可能并不总是 nil。请不要使用保留计数来确定对象是否占用内存,因为这是两个非常不同的事物;这就是我认为您感到困惑的地方。请查看我发布的链接。
    【解决方案2】:

    nil 上的release 是无操作的,所以总是可以的。而且它不会泄漏,因为您没有要开始的对象。

    UIImage* test = [UIImage alloc];
    

    test 本身已经是一个UIImage 对象(尽管您未能在这一行初始化它)。

    你真的应该总是在同一行(和同一个变量)上执行 alloc/init - 否则代码逻辑真的很难遵循。您的代码只生成一个对象,然后将其分配给另一个变量。

    这是一样的,但更清晰:

    UIImage* test = [[UIImage alloc] initWithContentsOfFile:path];
    UIImage* image = test;
    int n = [test retainCount]
    

    这里很明显testimage 是同一个对象(因此具有相同的retainCount)。每当您释放其中一个时,该对象就会消失(除非您之前 retain 它)。

    还请注意,retainCount不是您应该依赖或做出很多假设的东西。充其量通常是误导性的。

    【讨论】:

    • 如果 alloc/init 返回 nil,则没有需要释放的内存。一切顺利。并且在 nil 上调用 release 不会有什么坏处,这很方便。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-15
    • 2012-02-08
    相关资源
    最近更新 更多