使用点语法设置保留属性时使用自动释放?
Posted
技术标签:
【中文标题】使用点语法设置保留属性时使用自动释放?【英文标题】:Use autorelease when setting a retain property using dot syntax? 【发布时间】:2011-08-28 15:45:05 【问题描述】:我在一些示例代码中看到使用了autorelease
。我不熟悉需要这样做的实例。例如,如果我创建一个注释对象
头文件
@interface someViewController: UIViewController
Annotation *annotation;
@property (nonatomic, retain) Annotation *annotation;
@end
实现文件
@implementation someViewController
@synthesize annotation
@end
问题:如果我像这样在实现文件中初始化我的注释对象,这是正确的方法吗?
self.annotation = [[Annotation alloc] initWithCoordinate:location];
我需要为此设置自动释放吗?或者我可以按正常方式做,并在 dealloc 方法中添加释放?
【问题讨论】:
Autorelease vs. release 的可能副本,如果您花时间阅读它们,还有很多很多其他问题会回答这个问题:Search: iPhone retain property autorelease 这个:Release/autorelease confusion 可能是最好的问题之一。 【参考方案1】:这是正确的:
self.annotation = [[[Annotation alloc] initWithCoordinate:location] autorelease];
因为注解属性被声明为一个保留属性,所以分配给它会增加它的保留计数。
同样,您还需要在-dealloc
中发布 self.annotation。
简而言之:
init 会将保留计数设置为 1;
分配给self.annotation,将其设置为2;
再次执行主循环时,autorelease 会将其设置回 1;
dealloc中的release会将retain count设置为0,这样对象就会被释放);
在我看来,考虑autorelease
的最佳方式如下:autorelease
将在未来某个(近)点为您的对象“安排”一个“自动”release
(通常是当控制流程回到主循环,但细节隐藏在 Apple 手中)。
autorelease
主要与init
结合使用,特别是在以下情况下:
当你init
一个局部变量时,这样你就不必在它超出范围之前明确地release
它(主循环会为你做这件事);
具有retain
的属性,当您为他们分配一个他们应该唯一拥有的对象时;
具有增加保留计数的数据结构(NSMutableArray
、NSMutableDictionary
等):当您将其添加到此类数据结构时,您通常应该将 autorelease
新的 init
ed 对象添加到此类数据结构中。
除了案例 2,很明显使用 autorelease
是为了提高代码的可读性并减少出错的可能性(这意味着在所有其他情况下,您可以简单地 release
明确您的赋值之后或范围末尾的对象)。
在使用属性时,必须始终检查它们是否属于retain
或assign
/copy
情况;在第一种情况下,将新的init
ed 对象分配给属性通常需要autorelease
。
无论如何,我建议至少浏览一下memory management for ios 上的众多教程之一。
【讨论】:
一个小问题,如果你写annotation = [[Annotation alloc] initWithCoordinate:location];
没有self
,保留计数不会增加。【参考方案2】:
自动释放是告诉对象在离开作用域之前释放自己。
有时在你编码的时候,你会遇到这样的事情
- (void)doSomething
if(true)
NSString *foo = [[NSString alloc] initWithString:@"foo"];
//Some execution here
[foo release];
- (void)doSomething
if(true)
//By doing this is telling to to release foo object before getting out of the scope
//which is similar with above practice
NSString *foo = [[[NSString alloc] initWithString:@"foo"] autorelease];
//Or you can do it this way
NSString *foo = [[NSString alloc] initWithString:@"foo"];
[foo autorelease];
//Some execution carry on, it'll release foo before entering next scope
//这个超出范围
当然,释放对象并不意味着释放对象。 有时您会保留该对象,以便您仍然可以在其范围之外使用它。
从您的问题来看,如果您的对象位于您的头文件/接口中。 你应该在 dealloc 方法中释放它。 CMIIW。
【讨论】:
澄清一下,我的理解是即使对象在头文件中,我们可能仍然需要执行自动释放,例如 self.annotation = [[Annotation alloc]init... 发生.对吗? @Zhen 通常你会初始化你的接口对象(甚至让它为零)。因此在 dealloc 中释放是必须的。但是如果你有机会再次初始化你的对象(这会导致内存泄漏,因为你丢失了以前的内存地址),是的,你可以设置自动释放。请记住,当我们分配和初始化时,我们谈论的是内存地址。这是我所知道的,如果您想了解更多信息,可以阅读/询问有经验的程序员。以上是关于使用点语法设置保留属性时使用自动释放?的主要内容,如果未能解决你的问题,请参考以下文章