在这两种方法之间,哪个更好/更有效?更具体地说,应该使用哪个,或者是否有适当的时间使用一个而不是另一个?
UIImage *img = [UIImage imageWithContentsOfFile:filePath];
或者
UIImage *img = [[UIImage alloc] initWithContentsOfFile:filePath];
谢谢!
编辑:我应该提到我正在使用 ARC。
在这两种方法之间,哪个更好/更有效?更具体地说,应该使用哪个,或者是否有适当的时间使用一个而不是另一个?
UIImage *img = [UIImage imageWithContentsOfFile:filePath];
或者
UIImage *img = [[UIImage alloc] initWithContentsOfFile:filePath];
谢谢!
编辑:我应该提到我正在使用 ARC。
第一个返回一个autorelease
d 对象。该imageWithContentsOfFile:
版本很有可能调用标准构造函数,因此速度/效率不应有任何明显差异。两者在 ARC 环境中的执行和使用方式相同。
最大的区别在于objective-c
引用计数。当您init
拥有一个对象时,您就声称拥有它的所有权。这意味着您有责任在不再需要该对象时释放它,即通过调用[img release]
.
当您获得对名称以init
or以外的其他名称开头的方法的引用时copy
(我不确定是否有任何其他前缀),这些对象将注册到 anNSAutoreleasePool
并在池耗尽时自动释放。
你可以这样检查:
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
UIImage *img1 = [UIImage imageWithContentsOfFile:filePath];
UIImage *img2 = [[UIImage alloc] initWithContentsOfFile:filePath];
[pool drain];
NSLog(@"%@", [img1 retainCount]); // 1
NSLog(@"%@", [img2 retainCount]); // 0 or invalid mem access, not sure
要实现自动释放行为,当您为对象创建访问器并因此将所有权委托给访问器方法而不是调用方法时,您应该这样做,您可以执行以下操作:
[obj autorelease];
至于NSAutoreleasePool
不要太担心它的工作,因为文件NSApplicationMain
中的方法已经为您设置了一个池main.c
。
您可以在NSObject 协议参考和高级内存管理中进一步研究这种机制。
因为一开始我使用 alloc 声明我的所有图像,如果在某个函数结束时我返回了使用 alloc 创建的图像,我必须自动释放该图像,因为内存泄漏问题。现在使用第一个声明我不需要发布任何东西
当您“出售”一个对象时,这是完全正确的。但在其他情况下,当您在 iOS 上创建对象时,您可以在获取现成的自动释放对象和调用 alloc 然后释放之间进行选择,Apple 希望您使用 alloc 和 release,因为这样可以保持对象的生命周期简短且在您的控制之下。
这里的问题是,自动释放的对象存在于自动释放池中,并且可以堆积起来,直到池耗尽,无论何时。
另一件需要注意的是循环。您可能会在不知情的情况下生成自动释放的对象,它们只是堆积在池中。解决方案是在循环开始时创建自己的自动释放池,并在循环结束时释放它,这样每次循环都会释放对象。
编辑 - 2011 年 12 月 18 日:但是随着 iOS 5 和 ARC 的到来,自动释放机制效率更高,并且没有释放这样的东西,所以 alloc-init 和出售自动释放对象的便利构造函数之间的区别变得没有意义。(而且它现在是一个 @autoreleasepool 块而不是一个自动释放池(伪)对象。)