iOS的五个修饰符,strong、weak、assgin、retain、copy的用法。
用法
Name | Limit |
---|---|
strong | 只能用于修饰对象 |
retain | 只能用于修饰对象 |
copy | 只能用于修饰对象 |
weak | 只能用于修饰对象 |
assign | 能用于修饰对象和基本数据类型 |
栈赋值
栈赋值的场景为,目标指针指向栈上的对象, 以NSStackBlock为例:
1 | @property (nonatomic, strong) void(^strongVar)(); |
打印结果为:
1 | <__NSMallocBlock__: 0x600000051fa0> |
说明,对于栈赋值,strong、retian、copy,会在堆上复制一个,并指向该堆对象,而weak、assgin只会直接指向栈对象。一旦,栈对象被释放,再调用会引起Crash。
举例:
1 | -(void)test{ |
总结
Name | RetainCount | Usage |
---|---|---|
strong | 引用=1 | 在堆上复制一个,并指向它 |
retain | 引用=1 | 在堆上复制一个,并指向它 |
weak | 不影响引用 | 直接指向栈对象,栈对象被释放时,不会自动变成nil |
assign | 不影响引用 | 直接指向栈对象,栈对象被释放时,不会自动变成nil |
copy | 引用=1 | 在堆上复制一个,并指向它 |
堆赋值
堆赋值的场景为,目标指针指向堆上的对象, 以 NSMallocBlock为例:
1 | -(void)test{ |
打印结果为:
1 | <__NSMallocBlock__: 0x60800005fe30> |
说明,对于堆赋值,strong、retian、copy、weak、assign,都是直接指向该堆对象,会导致引用数+1,而weak,assgin不会改变引用数。其中,weak指向的对象如果被释放了,weak指针会自动置为nil,而assgin不会,一旦,堆对象被释放,再调用会引起Crash。
总结
Name | RetainCount | Usage |
---|---|---|
strong | 引用+1 | 直接指向堆对象 |
retain | 引用+1 | 直接指向堆对象 |
weak | 不影响引用 | 直接指向堆对象,堆对象被释放时,会自动变成nil |
assign | 不影响引用 | 直接指向堆对象,堆对象被释放时,不会自动变成nil |
copy | 引用=1(可变类型);引用+1(不可变类型) | 对于可变类型,在堆上复制一个,并指向它;对于不可变类型,直接指向它 |
常量赋值
常量赋值的场景为,目标指针指向常量空间上的对象, 以NSGlobalBlock为例:
1 | @property (nonatomic, strong) void(^strongVar)(); |
打印结果为:
1 | <__NSGlobalBlock__: 0x10c3050c0> |
说明,对于常量赋值,strong、retian、copy、weak、assign,都是直接指向该常量地址,由于常量的生命周期与进程一致,所以引用数没有意义。
总结
Name | RetainCount | Usage |
---|---|---|
strong | 引用无意义 | 直接指向该常量对象 |
retain | 引用无意义 | 直接指向该常量对象 |
weak | 引用无意义 | 直接指向该常量对象 |
assign | 引用无意义 | 直接指向该常量对象 |
copy | 引用无意义 | 直接指向该常量对象 |