assign:
assign
一般用来修饰基本的数据类型,包括基础数据类型(NSInteger,CGFloat)和C语言数据类型(int,float,double,char)等等。因为assign声明的属性,是不会增加引用计数的,也就是说声明的属性释放后也就没有了,及时其他对象引用了它也不会保留,只会造成crash。但是及时被释放,指针却还在,成为了
野指针
,如果新的对象被分配到了这个内存地址上,又会造成crash。所以一般只用来声明基本的数据类型,因为它们会被分配到
栈区
上,而栈取由系统
自动管理
,不会造成野指针。
retain:
与assign相对,我们要解决
对象
被其他对象引用后释放造成的问题,就需要用
retain
来声明。使用retain声明的对象会
更改引用计数
,每次被引用,引用计数都会
+1
,释放后就会
-1
。即使这个对象本身被释放了,只要还有对象在引用它,该对象就会
仍然持有
,不会出现任何问题。并且只有当引用
计数为0时
,就会被
dealloc
析构函数回收进内存。
copy:
最常见到的copy的声明使用是 NSString 等。copy与retain的
区别
在于:retain是拷贝内存指针地址,而copy是拷贝对象本身;也就是说retain是
浅复制
,copy是
深复制
;如果是浅复制,当修改对象值时,都会被修改,而深复制不会。之所以在
NSString
这一类有
可变类型对象
的身上使用
copy
关键字,是因为他们有可能和对应的可变类型如
NSMutableString
之间进行赋值操作,为了防止内容被改变,使用copy去深复制一份。copy工作由copy方法执行,此属性只对那些实现了
NSCopying
协议的
对象类型
有效。
weak:
weak是由ARC新引入的对象变量属性,weak类似于assign,叫
弱引用
,也是不增加引用计数,不同在于week指向对象类型时,当对象被释放会指向nil,而assign则会造成野指针。一般只有在防止循环引用时候使用;比如父类引用了子类,子类又引用父类;IBOutlet、Delegate等一般就是使用week,这是因为他们可能会在类外部被调用,防止循环应用。
strong:
strong也是由ARC新引入的对象变量属性,在ARC下,用strong代替了retain,叫
强引用
,会增加引用计数。,所有的局部变量代码中我们声明的变量默认都是强引用,不需要再额外使用
__strong
来修饰。
什么时候用 stong
/ weak
stong
weak
- 根视图和父视图需要使用
; 子视图使用strong
weak
- 没有强指针指向的对象使用
; 有强指针指向的可以可以strong
weak
__strong,__weak,__unsafe_unretained,__autoreleasing
的含义
__strong,__weak,__unsafe_unretained,__autoreleasing
在ARC情况下,对象类型的变量将有所有权修饰符
__strong
: 是缺省的关键词。
__weak
: 声明了一个可以自动nil化的引用。
__unsafe_unretained
: 声明一个弱引用,但是不会自动nil化,也就是说,如果所指向的内存区域被释放了,这个指针就是一个野指针了。
__autoreleasing
: 用来修饰一个函数的参数,这个参数在函数返回的时候会被自动释放。
ARC
声明属性时,对于
基本数据类型
默认关键字是 (atomic,readwrite,assign)
ARC
声明属性时,对于普通的
OC对象
默认关键字是 (atomic,readwrite,strong)
- 示例
扩展:
LLVM官网给出的一些示意,ARC里也可以使用retain等关键字
assign 等同于unsafe_retained
copy的作用和MRC一样,同时又有strong的效果
retain等同于strong
weak和unsafe_unretained的区别在于:weak降被释放指针赋值为nil,而unsafe_unretained则会成为野指针