1.delegate假如用 retain会有什么后果?
在 AController.m中的某个方法内有如下代码:
_bView = [[BView alloc]initWithFrame:frame];
_bView.delegate = self;
然后在 dealloc方法中释放 _bView:
_bView.delegate = nil;
release_nil(_bView);
假如这里 delegate用的是 retain, 那么 AController对象的引用计数被 _bView retain了一次 ,这样只有在 _bView释放时 AController对象才有可能被释放。而 _bView的释放又依赖于 AController的释放,这就造成了循环引用。 AController对象和 _bView永远得不到释放。
结论: delegate一定要用 assign,不能用 retain。
2 . AController中有个BController对象
BController *bController = [[BControlleralloc] init];
bController.parentController = self;
[self presentViewController:bController animated:YES];
[bController release];
与delegate同样的道理,这里的parentController只能用assign。
理由是,这里bController被alloc了一下,引用计数是1,被present之后,引用计数增加若干,假设增加了3(反正肯定不止增加1)。这时bController的引用计数为1+3=4。然后release一下,减一变为3。这个3要什么时候被减去变为0呢?推测是在AController被销毁的时候,通过[super dealloc];这句方法内部调用一系列的方法 来释放bController。这里假如parentController误声明为retain,则bController持有AController对象并使AController对象的引用计数+1,则AController中的dealloc永远不会被调用,BController中的dealloc永远也不会被调用。
3. ARC
简介:Objective-c中提供了两种内存管理机制MRC(Manual ReferenceCounting)和ARC(Automatic Reference Counting),分别提供对内存的手动和自动管理,来满足不同的需求。ARC是iOS 5推出的新功能,简单地说,就是代码中自动加入了retain/release,原先需要手动添加的用来处理内存管理的引用计数的代码可以自动地由编译器完成了。该机制在 iOS 5/ Mac OS X 10.7 开始导入,从Xcode4.2开始可以使用该机能。简单地理解ARC,就是通过指定的语法,让编译器(LLVM 3.0)在编译代码时,自动生成实例的引用计数管理部分代码。
优点:1)在很大程度上消除了手动内存管理的负担,同时省去了追查内存泄露和过度释放对象引起的繁琐操作;2)根据Apple的说法,ARC的效率反倒高。效率为什么会提高了呢?主要是之前通过autorelease释放的东西都是随着runloop在autorelease pool中一起释放的,而开启了ARC后,很多之前要autorelease的东西直接就通过类似手动管理的方式释放掉了,根本没放到autoreleasepool中,从而提升了效率。
缺点:1)部分流行的开源库还没有转为ARC; 2)网上有人发现,使用ARC时,对于非ARC代码,只需要在编的时候加上-FOBJ-ARC啥的就好了,实际上不是的。因为加上这个代码之后,一旦你的程序中有ARC和非ARC这两个CLASS之间交互的时候,就会莫名的出现内存泄露,而且泄漏得莫名其妙。3)ARC对Core Foundation支持的不好,仍然需要xxxxRetain, xxxxRelease;
建议:学习iOS开发内存这块是必须要清楚的,最好是刚开始学习写代码时手动管理内存,对iOS管理内存的机制比较清楚了后,再考虑要不要使用ARC(自动引用计数)机制。即使是使用ARC(自动引用计数)也要了解iOS的内存管理机制,如果你不了解iOS管理内存的机制,只会用ARC让系统帮你管理内存,可以说你的知识结构是有缺陷的,在解决一些程序中遇到的bug时会浪费掉大量的时间。所以通过手动管理内存来深刻理解iOS内存管理机制还是很有必要的。