2013-12-13 57 views
3

我是IOS开发新手,我已经开始学习客观的c程序对IOS 7,并且据我所知,由于自动引用,比以前更容易编写代码数数。有几件我不明白的事情。在MAIN方法中,我们有autoreleasepool块,所以我的第一个问题是,为了启用ARC,代码必须位于此块内?如果不是,那么autoreleasepool内部的代码和其他代码之间的区别是什么?关于ARC的困惑,自动发布

我的第二个问题是,当我正在编写我的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,结果有没有什么不同? (对象仍然在内存或没有)

回答

4

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

这个方案的一个问题是,它使得返回一个对象很尴尬,因为在你返回它之前你不能释放这个对象 - 如果你这样做了,它可能会在另一个方法使用它之前被销毁 - 但你不想要求其他方法来释放对象。这是autorelease池的用武之地。一个autorelease池可以让你将一个对象交给它,并且它承诺在稍后为你释放对象。在手动保留/释放(我们之前用于在ARC之前执行操作的方式)下,您通过将autorelease发送给对象来完成此操作。

好吧,然后ARC进入画面。 ARC唯一真正改变的地方是,你不是编写retainreleaseautorelease的编译器 - 编译器会为你插入它们。但是你仍然需要一个autorelease池来让自动释放的对象进入。

至于你的第二个问题:

我的最后一个问题是,是否有弧形或没有它,如果我们有一个方法内声明的指针变量,它的对象得到释放/销毁时,该方法返回/出口?

假设我们有这样的方法:

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

那么当我们调用这个方法,它退出时,会发生什么样的方法内定义的那些局部变量?如果我们使用ARC,结果有没有什么不同?

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

+0

感谢您的回复。只有一个问题仍然存在,如果ARC完成这项工作,那么拥有“autoreleasepool”的意义何在? –

+0

@aligh:ARC插入调用来保留,释放和自动释放,所以你不必这样做,但这些方法仍然是一如既往 - 你只是不是那个叫他们的人。即使编译器是编写调用的编译器,autorelease仍然会将对象放入自动释放池中,因此仍然需要有一个自动释放池供自动释放对象使用。 – Chuck

+0

非常感谢。您介意查看另一个问题,我询问了有关以下链接中的UINavigationController属性的问题吗? http://stackoverflow.com/questions/20572690/navigationcontroller-property-is-declared-in-uinavigationcontroller-h-but-is-a-p –

2

新iOS开发

最好不要担心,自动意味着你大多集中在其他事情上^)

做到这一点意思是这个块不知何故神奇地被应用于同一程序的任何其他类中的所有代码行

是的。您正在使用main函数,因此所有执行的代码都必须位于此函数内 - 您的应用一旦结束就会终止。除非你创建一个单独的线程,但很难做到这一点意外。

代码必须是此块

正如上面说的里面,所有的主线程代码将这个块内执行。

会发生什么样的方法

你保证,他们将返回前被销毁内部定义的局部变量。

2

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

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

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

我的第二个问题是,当我正在编写我的IPHONE程序时,我有一堆类和非那些代码都在“autoreleasepool”里面,只有MAIN方法中的代码。

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

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

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