简体   繁体   English

iPhone:使用保留vs自动释放

[英]iPhone: using retain vs autorelease

Which one of these is better practice? 哪个是更好的做法?

A) retain and release the object myself later A)稍后自己保留并释放对象

NSMutableArray* array = [[self getArray] retain];
....
[array release];

B) autorelease from the function returning the object B)从返回对象的函数中自动释放

getArray {
   NSMutableArray* returnedArray = [[[NSMutableArray alloc] init] autorelease];
   .....
   return returnedArray;
}

The simplest rule of thumb when it comes to memory management in Objective-C is that you should release anything that you've explicitly allocated (alloc), copied (copy), newed up (new), or retained (retain). 关于Objective-C中的内存管理,最简单的经验法则是,您应释放任何已明确分配(分配),复制(复制),更新(新)或保留(保留)的内容。

The release should be done within the scope of the aforementioned actions. 释放应在上述动作的范围内完成。 If you allocate space for an object that is returned by a method, you should autorelease it before returning it. 如果为方法返回的对象分配空间,则应在释放它之前自动释放它。 So, given the two options you've provided, B is the recommended practice. 因此,考虑到您提供的两个选项,建议您使用B。

If you want to return an object you have to use the second approach. 如果要返回对象,则必须使用第二种方法。 In all cases where possible you should use the retain-release approach because this uses less memory. 在所有可能的情况下,都应使用保留释放方法,因为这会占用较少的内存。

You could read and follow Apples guidelines on memory management and performance . 您可以阅读并遵循Apple关于内存管理性能的准则。

Personally I think the reasons for choosing one way over the other: 我个人认为选择其中一种方法的原因是:

Using Autorelease pros: 使用自动发行专家:

  • You can't stuff it up, memory will be freed at some point. 您无法将其填满,内存将在某个时候释放。 That I like to think of as "falling into the pit of success". 我想将其视为“成功之路”。

cons: 缺点:

  • Using autorelease a lot may cause you memory problems as lots of objects build up awaiting be released by the autorelease pools. 大量使用自动释放可能会导致内存问题,因为大量对象堆积起来,等待自动释放池释放。

Using retain/release pros: 使用保留/发布专家:

  • More control when your memory is used/freed. 使用/释放内存时的更多控制。
  • On ios apple recommends that you use release instead of autorelease whenever possible to keep the size of the pool small. 在ios上,Apple建议您尽可能使用release而不是autorelease来保持池的大小较小。

cons: 缺点:

  • Like C/C++ malloc/free new/delete you have to be careful to keep them matched up and it is easy to stuff that up, causing memory leaks. 像C / C ++ malloc / free new / delete一样,您必须小心保持它们匹配,并且很容易将其塞满,从而导致内存泄漏。
  • For member variables you have no choice, retain/release is it. 对于成员变量,您别无选择,保留还是释放。

I think, whichever style you choose comes down to the situation your code is in and choosing the best style based on there pro's and con's. 我认为,无论选择哪种样式,都取决于您的代码所处的情况,并根据优缺点选择最佳样式。 I don't think there is any one answer to this. 我认为对此没有任何答案。

  1. If you new , alloc init , retain , or copy (NARC) an object, you have to release it. 如果您newalloc initretaincopy (NARC)对象,则必须释放它。
  2. When the name of a method starts with any of those words, it means it's being created for the caller, who has the responsibility to release the object when he is done with it. 如果方法的名称以任何这些词开头,则表示该方法是为调用方创建的,调用方负责在完成处理后release对象。
    Otherwise the method returned is not owned by the caller, and he has to indicate he wants to keep it calling retain on the object. 否则,返回的方法不归调用方所有,并且他必须指示他要保持该方法的调用,方法是retain对象。
  3. If you can choose, don't abuse autorelease when memory is a concern. 如果可以选择,请在担心内存时不要滥用自动释放功能。

Some comments: 一些评论:

  • The first rule logically results in the second. 第一条规则在逻辑上导致第二条。 Example: if the outcome of a function (the returned object) survives the execution of the function, all the function can do is autorelease the object. 示例:如果某个函数(返回的对象)的结果在函数执行后仍然存在,则该函数所能做的就是自动释放该对象。
  • Unless there is a memory/performance concern, the overhead of automatic memory management is better than the memory leak chances plus the increased developing time. 除非存在内存/性能方面的问题,否则自动内存管理的开销要好于内存泄漏的机会再加上开发时间。
  • Try to retain/release symmetrically. 尝试对称地保留/释放。 Example: if you retained on init, then release on dealloc. 示例:如果您保留init,则在dealloc上释放。 Same for viewDidLoad/viewDidUnload. 与viewDidLoad / viewDidUnload相同。
  • If you use @property(retain) you have to release in dealloc. 如果使用@property(retain),则必须在dealloc中释放。

Example: 例:

 // created with autoreleased, just call retain if you intend to keep it
 NSString *orange = [NSString stringWithString:@"orange"];
 // created for the caller, you'll have to release it when you are done
 NSObject *apple = [NSString initWithString:@"apple"];

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM