首页 > 代码库 > assign/copy/retain/strong/weak/readyonly/readwrite/nonatomic/atomic

assign/copy/retain/strong/weak/readyonly/readwrite/nonatomic/atomic

arc其实并不是所谓的垃圾回收机制,其实arc只是编译器的一种特性,编译器会在编译阶段插入相应的内存管理代码,以实现自动的内存管理,这样就减少了因为程序员的一时疏忽或者项目过大而失误从而造成内存泄露,因为是编译器自动完成的代码插入所以arc的效率要高于垃圾回收机制.

在arc机制下dealloc中会由编译器自动插入释放属性的代码因此也不需要手动调用[super dealloc],当然arc只能管理foundation层的对象对于core foundation层的变量需要程序员手动去释放或者使用桥接将其转交给foundation层对应的变量去处理.

atomic和nonatomic(原子性)

在设置成员变量时默认是atomic也就是操作的原子性,这样能够提供属性的多线程安全性.

也就是说在同一时间在所有线程下只能同时执行一次setter方法,以防止在进行某一次赋值的时候其他线程也在进行赋值,造成数据的混乱.

当设置了某一个成员变量为nonatomic时则不会提供多线程安全,在一般情况下如果没有在多线程下使用该变量的时候建议设置成这样,少了一层线加锁会提升程序的性能

setter方式:

assign (默认值)

直接赋值,也就是说访问器会直接把传入的值赋值给成员变量,不会进行多余的处理,如果传入的参数遵守了NSCopying协议的话就需要显式的标记assign以此来通知编译器我确实需要直接赋值,当然值得一提的是,当使用assign赋值一个指针的时候需要注意的是,赋值完成后会有两个指针变量指向同一块内存区域,当有一个指针对该区域进行释放了之后,有可能会发生野指针错误,所以说,assign般用于oc的基本数据类型(NSInteger,CGFloat)以及c数据类型(int,float,double,char等)

weak 在arc中替代assign

首先需要说一下weak也是直接赋值,不同的是使用weak会在属性指向的内存空间被释放掉之后给该属性赋值一个nil,这样就很好地避免了野指针错误,

delegate需要标记为weak用来防止循环引用,因为arc模式下可以理解为有强指针指向该对象时该对象就不会被释放,当两个对象互相之间是强引用或者中间通过其他对象实现互相之间的强引用时就是循环引用,也就是说在发生循环引用时不论怎样对象都不会被释放.

 

copy

首先我们需要了解浅复制和深复制,简单的说就是浅复制只是复制了指针而指针指向的内容不会被复制,深复制就是复制存放内容堆内存的空间,将堆中的内容拷贝一份并将属性指向新的地址,新对象的retaincount为1.

拷贝方式就是在赋值的时候将内容复制一份在新的内存空间,然后将新地址赋值给成员变量,当然值得一提的是当赋值的对象中含有指针的话,那么就会只复制指针地址,不会复制指向的内容,比如说当copy的是一个nsarray时因为数组中装的只有元素指针,所以只有元素的指针会被复制,而数组元素的地址不变这就是所谓的浅复制了.

 

retain

当属性被标记为retain的时候,生成的setter方法内部执行如下步骤,判断新的值和旧值是否相等,如果不相等则release旧值retain新值并将新值赋给成员变量,这里可以理解为浅复制,即只将指向的地址赋给成员变量

 

strong

在arc下使用其实相当于retain是默认属性类型

 

readyonly/readwrite

读写权限设置,某些成员变量如果不希望被别人更改的时候必须要设置readonly,这点是非常值得注意的,试想你花了很大的精力去得到这个值,其他人一不小心给你修改了的话会造成多么严重的后果就不用我来说了.