alloc语句中是否需要设置autorelease?

发布于 2024-11-18 20:19:18 字数 363 浏览 4 评论 0原文

假设下面的代码,

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


[str autorelease];

我已经看过很多次了,大多数程序员确实更喜欢放置 alloc, init在一个语句中同时进行。

在这里,我询问是否可以将 autorelease 划分为下一个语句。

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

Assume following code,

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


[str autorelease];

I have seen many times that, Most of the programmers do prefer to put alloc, init simultaneously within one statement.

Here, I am asking for the possibility of dividing autorelease for next statement.

  • For example, It is recommended to put init with alloc statement.
    Is it same for autorelease ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

楠木可依 2024-11-25 20:19:18

大多数程序员确实更喜欢在一条语句中同时放置 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];

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

Most of the programmers do prefer to put alloc, init simultaneously within one statement.

That’s because the instance returned by the initialiser is not necessarily the one returned by +alloc. For example, this is wrong and will crash your program:

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

because in this case -initWithString: causes the deallocation of the previous instance, and str ends up pointing to a deallocated object. This can be fixed by:

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

so that str points to the different instance returned by -initWithString:. The form:

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

guarantees that str points to the correct instance.


That said, -autorelease is different. Unless it’s been overridden by an evil djinn, it always returns the receiver itself. This means that both:

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

and:

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

are correct and work in the same manner.

As for the distinction between:

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

and:

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

some people prefer to use -autorelease in tandem with allocation to avoid forgetting to autorelease the instance later. Others prefer to place it in the return statement (if any):

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

to make (more) explicit that the method/function returns an autoreleased object.

失去的东西太少 2024-11-25 20:19:18

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

return [object autorelease]

当您想要将对象返回给调用者时。

You can use autorelease anywhere within the scope, in fact the most common usage is

return [object autorelease]

When you want to return an object to the caller.

不可一世的女人 2024-11-25 20:19:18

你可以这样做

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;  

或 this

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

或 this

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

在这种情况下,我认为您不会看到第一个选项。毕竟,当你也可以进行释放时,为什么要进行自动释放呢?你经常看到第二个选项。这意味着您不必记住稍后进行发布。你也经常看到第三个选项。它在 iOS 上的优点是不会保留不必要的内存超过必要的时间。

You can do this

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

or this

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

or this

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

I would go with either the second or third, but it's personal preference.

If it's a temporary object that you don't return, you can do this:

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

or this

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

or this

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

In this case, I don't think you ever see the first option. After all, why do autorelease when you can also do release. You see the second option quite a lot. It means you don't have to remember to do the release later. You also see the third option a lot. It has the advantage on iOS of not holding on to unneeded memory for longer than necessary.

如日中天 2024-11-25 20:19:18

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

Yes, you can put autorelease in next statement, but the scope of this str will be local and when control is out of scope, this string will be released....

请远离我 2024-11-25 20:19:18

如果您将 autorelease 放在下一个语句中,则不是问题。

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

应用程序工具包在事件循环的每个周期开始时在主线程上创建一个自动释放池,并在结束时耗尽它,从而释放在处理事件时生成的任何自动释放对象。如果您使用应用程序工具包,那么您通常不必创建自己的池。然而,如果您的应用程序在事件循环中创建了大量临时自动释放对象,则创建“本地”自动释放池可能会有所帮助,以帮助最大限度地减少峰值内存占用。

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

例如,对于辅助线程:

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

// Code benefitting from a local autorelease pool.

[pool release];

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

如果你的项目是在ARC下开发的,你就不用再担心retain、release、autorelease了。苹果推荐使用ARC环境。

Not an issue if you put autorelease in the next statement.

autorelease object is automatically put into autorelease pool, when the scope of that object ends. Means, compiler automatically adds release message when scope of that object ends and in that case, you don't have to write release message for that object. An autorelease pool stores objects that are sent a release message when the pool itself is drained.

The Application Kit creates an autorelease pool on the main thread at the beginning of every cycle of the event loop, and drains it at the end, thereby releasing any autoreleased objects generated while processing an event. If you use the Application Kit, you therefore typically don’t have to create your own pools. If your application creates a lot of temporary autoreleased objects within the event loop, however, it may be beneficial to create “local” autorelease pools to help to minimize the peak memory footprint.

On main thread, [myObj autorelease] will automatically throw myObj into pool, at the end of perticular event loop, managed by system itself. But, to use [myObj autorelease] in case of secondary threads, you will have to use NSAutoreleasePool. Otherwise if a pool is not available, autoreleased objects do not get released and you leak memory.

For example, for secondary threads:

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

// Code benefitting from a local autorelease pool.

[pool release];

Remember, never release an object after pool itself has been released. This will either cause a crash or any unexpected output. I mentioned this because, I have paid a big cost of making this mistake.

If your project is developed under ARC, you don't have to worry anymore about retain, release, autorelease. Apple recommends to use ARC environment.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文