很久没有更新日志了,最近的一个月经历了一段炼狱般的开发周期,那动不动加班到凌晨几点的日子,说多了都是泪。。。
项目组在三周时间内完成了两个月的工作量,疯狂的赶工期,使得开发过程中没时间研究某个功能使用哪种方式更好,只求能实现,因此也没学到什么新东西,唯一的收获就是学会了ARC的基本使用。
可能是用惯了手动内存管理,而且基本上不会有内存泄露的的情况发生,当项目组领导说在新项目中要使用ARC的时候,还有一定的抵触情绪。被赶鸭子上架般的强制要求使用了以后,慢慢被它的优点吸引,ARC确实大大减少了我们开发过程中在内存方面花费的时间。ARC的使用心得如下:
当前ARC是和IOS5一块发布的,很多人就以为只有IOS5以后才可以使用,事实上ARC 是 LLVM 3.0 编译器的新特性。从OS X v10.6和v10.7上的64位应用,以及IOS4和IOS5开始,Xcode4.2版本开始,都可以使用。
当初抵制使用ARC的另一个原因,竟然是以为它会降低应用的性能,我把它和OS X和Java中的垃圾回收机制混为一谈了,现在想想真是可笑。好吧这个问题的答案是,使用ARC几乎不会降低性能,甚至还有可能提示性能。
官网上给的解释是:
It depends on what you’re measuring, but generally “no.” The compiler efficiently eliminates many extraneous retain
/release
calls and much effort has been invested in speeding up the Objective-C runtime in general. In particular, the common “return a retain/autoreleased object” pattern is much faster and does not actually put the object into the autorelease pool, when the caller of the method is ARC code.
ARC主要可能从两个方面使性能提升:
①编译器会减少很多外来的retain/release调用,这在运行时会有助提升性能
②不需要将返回的autoreleased类型的对象加入到autorelease pool中,也能在一定程度上提升性能
事实上,上述两条都是ARC在内存管理时优化性能的举措,它的实现机制会不会导致性能降低呢?
ARC的英文全名是:Automatic Reference Counting,是编译器提供的管理Objective-C对象内存的一个机制。它并不是像垃圾回收机制那样,有一个负责内存回收的系统,而是仍然以引用计数为基础,只是开发者可以像使用垃圾回收机制那样,不用再(或者说只需要做少量的工作)为对象什么时候需要增加引用计数,什么时候需要减少引用引用计数而绞尽脑汁,编译器会为我们做好一切:在编译阶段,编译器会在需要retain或release对象的地方自动为我们加上对应的代码。官方文档提供的图片很形象:
总之,ARC的出现,让我们可以将精力集中在功能代码上。
只有很简单的一句话:一个Object-C对象存在strong类型的指针指向时,该对象就不会被释放。
属性、关键字和对应的所有权关系如下:
其中,属性值一列都是用于声明@property属性声明时用的,编译器编译后会将这些属性值转换成对应的关键字;关键字是用于声明属性列表或普通实例变量指针的。
①strong
该属性值对应 __strong 关键字,即该属性所声明的指针变量将成为对象的持有者。strong是指向Objective-C对象指针的默认属性。
②weak
该属性对应__weak关键字,与__weak定义的变量一致,该属性所声明的变量将没有对象的所有权,并且当对象被破弃之后,对象将被自动赋值nil。
③unsafe_unretained
等效于__unsafe_unretaind关键字声明的变量;像上面说明的,iOS 5之前的系统用该属性代替 weak 来使用。
④copy
也是对象的所有者,与strong的区别是声明的指针变量是拷贝对象的持有者。
⑤assign
一般数值型变量用该属性声明,比如,int, BOOL,但无需显示写出,因为数值型变量的默认属性类型就是assign
⑥retain
该属性与strong功能相同。
上述的6个属性都可以在ARC中使用,但是assign和retain毕竟是MRC中的东西,而且assign和weak相比还是有不足之处的(下文会介绍),所以ARC中只推荐使用strong、weak、copy三个属性。
①只有一个内存管理关键字时
规范的写法如下所示:
//规范的写法
MyClass * __weak myWeakReference;
不规范的写法是:
//不规范的写法
__weak MyClass * myWeakReference;
大家尽量按照第一种苹果推荐的规范写法编程。
②还有其它关键字时
规范写法:
__block NSString * __weak myString
相同点:
指向的对象都是随时有可能被释放,即不拥有指向的对象
不同点:
①weak只能用来声明Objective-C对象,assign既可以用来声明对象,也可以用来声明数值型变量;
②很关键的一点区别,当一个weak关键字声明的指针指向的对象被释放掉得时候,该指针会自动的被指向nil,这就大大降低了程序崩溃的可能性!!!而assign不存在该特性
使用@property声明或作为普通实例变量声明的指向Objective-C对象的指针属性默认都是strong;而使用@property声明的数值型变量属性默认的是assign,普通的数值型变量的属性是__unsafe_unretaind。