使用iPhone上的obj-c,自动释放所有内容而不是释放是否有任何伤害?
例如,这段代码:
NSString *recipe = [[NSString alloc] initWithUTF8String:sqlite3_column_text(dbps,0)];
[arr addObject:recipe];
[recipe release];
当我创建配方nsstring时,可以通过自动释放配方nsstring缩短为两行:
NSString *recipe = [[[NSString alloc] initWithUTF8String:sqlite3_column_text(dbps,0)] autorelease];
[arr addObject:recipe];
这有什么缺点吗?我发现它更适合我的编码风格。谢谢大家。
答案 0 :(得分:6)
缺点是对象稍后会被释放。在大多数情况下,这不会是一个问题,但如果您在紧密循环中分配和自动释放数千个对象,这种开销可能会累积到影响性能的程度,甚至会导致应用程序耗尽内存。
无论如何,您可能想要使用:
[NSString stringWithUTF8String:sqlite3_column_text(dbps,0)];
而不是
[[[NSString alloc] initWithUTF8String:sqlite3_column_text(dbps,0)] autorelease];
答案 1 :(得分:2)
如果对象的作用域之外没有作用域,则应始终将其释放,以最大限度地减少应用程序消耗的内存量。
如果让对象一直存在,直到自动释放池启动,可能需要分配大量不需要的内存。这对于iOS 4和快速应用切换尤为重要,其中内存也分配给后台的应用程序。
你自己的内存占用越低,你的应用程序在后台运行时不会被终止的可能性越大。
答案 2 :(得分:1)
以下是我对这个问题的理解,如果我说错了,我肯定会被判处死刑;)
init
+ release
将比autorelease
更快。大部分时间表现都不是问题autorelease
。如果你想要一个物体,你需要手动release
或将你自动释放的obj粘贴在一个retain
的属性中,以便你以后可以获得它,否则你的obj将被释放为一旦超出范围init
+ release
,您可以更好地控制正在发生的事情,这对于高级多线程场景(特别是现在GCD普遍存在)非常有用。autorelease
大部分时间都可能很好,只要你理解reference counting是如何工作的,但不要把它当成银弹。您仍然可以使用autorelease
错误地泄漏大量内存。答案 3 :(得分:1)
我会回答这个问题:release
的主要劣势是很容易忘记的。对本地变量或实例变量的赋值看起来非常相同(如果不在初始化程序中分配,它们完全相同):
Foo * a = [[Foo alloc] init];
myFoo = [[Foo alloc] init];
这个以及类似的问题导致了一系列潜在的问题:
就个人而言,重构代码时内存泄漏的开销比一些自动释放的对象的开销要差。我偶尔会重构代码,所以看起来像这样:
FooView * v = [[[FooView alloc] initWithFrame:CGRectZero] autorelease];
// set up v...
myFoo = [v retain];
为了完整性,如果你在循环中做了很多事情(例如测试代码),你可以在每次迭代结束时使用类似的东西自动释放:
for (size_t n = 100000; n--; ) {
NSAutoreleasePool * pool = [NSAutoreleasePool new];
// ... allocate and autorelease some stuff ...
[pool release]; pool = nil;
}
如果您担心效率,可以使用(例如)CFString函数获得显着的加速 - Objective-C开销对于小字符串非常重要。
答案 4 :(得分:-2)
问题是当你进行自动释放时,你实际上并没有释放该对象,而是将其添加到当前的自动释放池中。当你释放每次通过主循环完成的池时,对象将被有效释放。
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
int retVal = UIApplicationMain(argc, argv, nil, nil);
[pool release];
你可以创建自己的自动释放池,但我不确定它会比简单地使用release更好。