使用点语法设置保留属性时使用自动释放?

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它(主循环会为你做这件事);

    1234563 /p>

    具有retain 的属性,当您为他们分配一个他们应该唯一拥有的对象时;

    具有增加保留计数的数据结构(NSMutableArrayNSMutableDictionary 等):当您将​​其添加到此类数据结构时,您通常应该将 autorelease 新的 inited 对象添加到此类数据结构中。

除了案例 2,很明显使用 autorelease 是为了提高代码的可读性并减少出错的可能性(这意味着在所有其他情况下,您可以简单地 release 明确您的赋值之后或范围末尾的对象)。

在使用属性时,必须始终检查它们是否属于retainassign/copy 情况;在第一种情况下,将新的inited 对象分配给属性通常需要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 中释放是必须的。但是如果你有机会再次初始化你的对象(这会导致内存泄漏,因为你丢失了以前的内存地址),是的,你可以设置自动释放。请记住,当我们分配和初始化时,我们谈论的是内存地址。这是我所知道的,如果您想了解更多信息,可以阅读/询问有经验的程序员

以上是关于使用点语法设置保留属性时使用自动释放?的主要内容,如果未能解决你的问题,请参考以下文章

在swift中实现swiftUI中的链式语法

属性存取直接访问实例变量

我应该在重新分配之前调用分配给保留属性的自动释放对象的释放吗?

OC - 属性点语法

3.属性点语法

获取对象属性两种方法的差别