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

时间:2011-05-19 07:33:00

标签: objective-c cocoa-touch ios memory-management autorelease

我在一些示例代码中看到使用了autorelease。在需要时我不熟悉这些实例。例如,如果我创建注释对象

标头文件

@interface someViewController: UIViewController 
{
    Annotation *annotation;
}

@property (nonatomic, retain) Annotation *annotation;

@end

实施档案

@implementation someViewController
@synthesize annotation
@end

问题:如果我在实现文件中初始化我的注释对象,这是正确的方法吗?

self.annotation = [[Annotation alloc] initWithCoordinate:location];

我需要为此设置自动释放吗?或者我可以按正常方式执行此操作并在dealloc方法中添加发布吗?

2 个答案:

答案 0 :(得分:15)

这是正确的:

self.annotation = [[[Annotation alloc] initWithCoordinate:location] autorelease];

因为annotation属性被声明为retain属性,所以赋值给它会增加其保留计数。

您还需要在-dealloc中发布self.annotation。

简而言之:

  1. init会将保留计数设置为1;

  2. 分配给self.annotation,将其设置为2;

  3. autorelease会在主循环再次执行时将其设置为1;

  4. 在dealloc中释放会将保留计数设置为0,以便释放对象;

  5. 在我看来,考虑autorelease的最佳方式如下:autorelease将为您的对象在某些(近)点“安排”“自动”release未来(通常在控制流程返回主循环时,但细节隐藏在Apple手中)。

    autorelease主要与init结合使用,特别是在以下情况下:

    1. 当你init一个局部变量时,所以在它超出范围之前你没有明确地release它(主循环会为你做这个); < / p>

    2. 当你返回一个指向你刚创建的对象的指针而没有保留它的所有权时(create/make*种选择器的典型情况,接收器需要retain它才能获得所有权);

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

    4. 包含增加保留计数(NSMutableArrayNSMutableDictionary等)的数据结构:添加时,通常应autoreleaseinit ed对象这种数据结构。

    5. 除了案例2之外,很明显autorelease的使用意味着提高代码的可读性并减少错误的可能性(这意味着在所有其他情况下,你可以简单地{{1}在赋值之后或在作用域的末尾显式地表示你的对象。)

      使用属性时,您必须始终检查它们是release还是retain / assign情况;在第一种情况下,为属性分配新的copy ed对象通常需要init

      无论如何,我建议至少浏览一下memory management for iOS上的许多教程。

答案 1 :(得分: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。