关于ARC,AutoRelease的困惑

时间:2013-12-13 18:08:56

标签: ios iphone objective-c

我是IOS开发的新手,我已经开始学习目标c来编写IOS 7.我知道,由于自动引用计数,现在编码比现在更容易。 还有一些我不明白的事情。在MAIN方法中我们有autoreleasepool块,所以我的第一个问题是,为了启用ARC,代码必须在这个块内?如果不是,那么autoreleasepool里面的代码与其他代码之间的区别是什么?

我的第二个问题是,当我编写我的IPHONE程序时,我有很多类,而不是那些代码在内部" autoreleasepool" ,只有MAIN方法中的代码。

 int main(int argc, char * argv[])
 {
     @autoreleasepool {
    return UIApplicationMain(argc, argv, nil, 
    NSStringFromClass([HomepwnerAppDelegate class]));
 }
}

所以,这是否意味着这个块以某种方式神奇地应用于同一程序的任何其他类中的所有代码行?

我的最后一个问题是,无论是使用ARC还是没有它,如果我们在方法中有一个声明的指针变量,当方法返回/退出时,对象是否被释放/销毁?

假设我们有这样的方法:

- (void)doSomething {
 NSMutableArray *allItems = [[NSMutableArray alloc] init];
 NSString *myString = @"sample string";
 [allItems addObject:myString]
 }

然后当我们调用此方法并退出时,方法内定义的局部变量会发生什么?如果我们使用ARC,结果是否有任何差异? (对象仍在内存中)或

3 个答案:

答案 0 :(得分:4)

自动释放池比ARC早约15年。 Cocoa使用引用计数内存管理方案,其中(概念上,至少)对象创建时引用计数为1,retain将其增加1并且release将计数减少1,并且当计数变为0时,对象被销毁。

这个方案的一个问题是它使返回一个对象有点笨拙,因为你不能在返回它之前释放它 - 如果你这样做了,它可能会在其他方法使用它之前被销毁 - 但是您不希望要求其他方法释放该对象。这是自动释放池的用武之地。自动释放池允许您将对象传递给它,并且它承诺稍后为您释放对象。在手动保留/释放(我们以前在ARC之前做事的方式)中,您通过将autorelease发送到对象来完成此操作。

好的,那么ARC就会出现。 ARC唯一真正改变的是你不再是写retainreleaseautorelease的人 - 编译器会为你插入它们。但是你仍然需要一个自动释放池供自动释放的对象进入。

至于你的第二个问题:

  

我的最后一个问题是,无论是使用ARC还是没有它,如果我们在方法中有一个声明的指针变量,当方法返回/退出时,对象是否被释放/销毁?

     

假设我们有这样的方法:

- (void)doSomething {
    NSMutableArray *allItems = [[NSMutableArray alloc] init];
    NSString *myString = @"sample string";
    [allItems addObject:myString]
}
     

然后当我们调用此方法并退出时,方法内定义的局部变量会发生什么?如果我们使用ARC,结果有什么不同吗?

如果您正在使用ARC,编译器将释放由局部变量引用的任何对象。如果你不使用ARC,你需要自己编写[allItems release],因为超出范围的变量不会神奇地导致它所引用的对象被释放。

答案 1 :(得分:2)

  

IOS开发新手

最好不要担心,自动意味着你主要专注于其他事情^)

  

这是否意味着这个块以某种方式神奇地应用于同一程序的任何其他类中的所有代码行

是。你在main函数中,所以执行的所有代码都必须在这个函数中 - 你的应用程序将在它结束时终止。除非你创建一个单独的线程,但是很难这样做。

  

代码必须在此块中

如上所述,主线程上的所有代码都将在此块中执行。

  

在方法

中定义的那些局部变量会发生什么

您可以保证在返回之前将其销毁。

答案 2 :(得分:2)

  在MAIN方法中我们有autoreleasepool块,所以我的第一个问题是,为了启用ARC,代码必须在这个块内?如果不是,那么autoreleasepool中的代码与其余代码之间的区别是什么?

通过相应的Objective-C编译器设置启用ARC。如果您在最新版本的Xcode中创建一个新项目,它将默认启用。

@autorelease关键字将大括号内的代码放入自动释放池范围。自动释放池既可用于ARC,也可用于手动内存管理。

  

我的第二个问题是,当我编写我的IPHONE程序时,我有很多类,而且这些代码中没有这些代码在“autoreleasepool”中,只有MAIN方法中的代码。

iOS应用程序是基于事件的。当您调用UIApplicationMain函数处理触摸事件,通知等时,主线程启动事件循环。此事件循环具有自己的自动释放池,在循环迭代结束时自动释放对象。此自动释放池与您在main函数中看到的自动释放池无关。

  

我的最后一个问题是,无论是使用ARC还是没有它,如果我们在方法中有一个声明的指针变量,当方法返回/退出时,对象是否被释放/销毁?

如果使用ARC,则将释放对象(除非从方法返回对对象的引用)。在MMR中,您需要手动发送release消息以销毁对象。