是否有必要在alloc语句中设置autorelease?

时间:2011-07-04 09:36:48

标签: iphone objective-c nsstring

假设以下代码,

NSString *str=[[NSString alloc] initWithString:@"sagar"];


[str autorelease];

我已经多次看到,大多数程序员都喜欢同时放置 alloc init 在一份声明中。

在这里,我要求为下一个声明划分自动释放的可能性。

  • 例如,建议将init与alloc语句放在一起。 autorelease 是否相同?

5 个答案:

答案 0 :(得分:8)

  

大多数程序员都喜欢在一个语句中同时放置alloc,init。

这是因为初始化程序返回的实例不一定是+alloc返回的实例。例如,这是错误的并且会使程序崩溃:

NSString *str = [NSString alloc];
[str initWithString:@"sagar"];

因为在这种情况下-initWithString:导致前一个实例的重新分配,str最终指向一个解除分配的对象。这可以通过以下方式解决:

NSString *str = [NSString alloc];
str = [str initWithString:@"sagar"];

以便str指向-initWithString:返回的不同实例。表格:

NSString *str = [[NSString alloc] initWithString:@"sagar"];

保证str指向正确的实例。


那就是说,-autorelease是不同的。除非它被一个邪恶的神灵所覆盖,否则它总会让接收器本身返回。这意味着两者:

NSString *str = [[NSString alloc] initWithString:@"sagar"];
str = [str autorelease];

NSString *str = [[NSString alloc] initWithString:@"sagar"];
[str autorelease];

是正确的,并以同样的方式工作。

至于区别:

NSString *str = [[[NSString alloc] initWithString:@"sagar"] autorelease];

NSString *str = [[NSString alloc] initWithString:@"sagar"];
…
[str autorelease];

有些人更喜欢与-autorelease配合使用,以避免以后忘记自动释放实例。其他人更喜欢将其放在return语句中(如果有的话):

NSString *str = [[NSString alloc] initWithString:@"sagar"];
…
return [str autorelease];

使(更)明确表示方法/函数返回一个自动释放的对象。

答案 1 :(得分:4)

您可以在范围内的任何位置使用自动释放,实际上最常见的用法是

return [object autorelease]

如果要将对象返回给调用者。

答案 2 :(得分:4)

你可以这样做

MyObject* foo = [[MyObject alloc] init];
...
[foo autorelease];
...
return foo;

或者

MyObject* foo = [[MyObject alloc] init];
...
...
return [foo autorelease];

或者

MyObject* foo = [[[MyObject alloc] init] autorelease];
...
...
return foo;

我会选择第二个或第三个,但这是个人偏好。

如果它是你没有返回的临时对象,你可以这样做:

MyObject* foo = [[MyObject alloc] init];
...
[foo autorelease];
...
return somethingElse;  

或者

MyObject* foo = [[[MyObject alloc] init] autorelease];
...
...
return somethingElse;    

或者

MyObject* foo = [[MyObject alloc] init];
...
[foo release];
...
return somethingElse;  

在这种情况下,我认为你没有看到第一个选项。毕竟,为什么在你也可以释放时自动释放。你会看到第二个选项。这意味着您不必记得以后再发布。你也经常看到第三个选项。它在iOS上的优点是不会长时间不必要地占用不需要的内存。

答案 3 :(得分:3)

是的,你可以在下一个语句中放入autorelease,但是这个str的范围是本地的,当控制超出范围时,这个字符串将被释放....

答案 4 :(得分:0)

如果您在下一个语句中添加 autorelease ,则不会出现问题。

当该对象的范围结束时,

autorelease 对象将自动放入自动释放池中。意味着,编译器会在该对象的范围结束时自动添加 release 消息,在这种情况下,您不必为该对象编写 release 消息。自动释放池存储在池本身耗尽时发送释放消息的对象。

Application Kit在事件循环的每个循环开始时在主线程上创建一个自动释放池,并在最后将其排出,从而释放处理事件时生成的任何自动释放的对象。如果您使用Application Kit,则通常不必创建自己的池。但是,如果您的应用程序在事件循环中创建了许多临时自动释放的对象,那么创建“本地”自动释放池以帮助最小化峰值内存占用量可能是有益的。

在主线程上, [myObj autorelease] 会在系统本身管理的特定事件循环结束时自动将myObj抛入池中。但是,要在辅助线程的情况下使用 [myObj autorelease] ,您必须使用NSAutoreleasePool。否则,如果池不可用,则自动释放的对象不会被释放并且您会泄漏内存。

例如,对于辅助线程:

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

// Code benefitting from a local autorelease pool.

[pool release];

请记住,在池本身释放后永远不会释放对象。这将导致崩溃或任何意外输出。我之所以提到这一点是因为,我付出了很大的代价来解决这个错误。

如果您的项目是在ARC下开发的,那么您不必再担心保留,释放,自动释放。 Apple建议使用ARC环境。