假设以下代码,
NSString *str=[[NSString alloc] initWithString:@"sagar"];
[str autorelease];
我已经多次看到,大多数程序员都喜欢同时放置 alloc , init 在一份声明中。
在这里,我要求为下一个声明划分自动释放的可能性。
答案 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环境。