weak、strong、copy、assign
2020-05-29 本文已影响0人
冷武橘
一、属性用weak和assign的区别
- weak:用来修饰oc对象。
- assign:一般用来修饰基本数据类型;也可以用来修饰oc对象。
- 当assign修饰oc对象时,生成的成员变量的指针类型是__unsafe_unretained(弱引用)修饰的对象被释放后,指针不会置空,而是变成一个野指针,那么此时如果访问这个对象的话,程序就会Crash,抛出BAD_ACCESS的异常;当weak修饰oc对象时,生成的成员变量的指针类型是__weak(弱引用),修饰的对象被释放后,指向对象的指针会置空,也就是指向nil,不会产生野指针;
深拷贝和浅拷贝
二、strong和copy
@interface Student : NSObject
@property(nonatomic,strong)NSString*name;
@property(nonatomic,copy)NSString*name1;
@end
NSMutableString *string = [[NSMutableString alloc]initWithString:@"1234"];
Student *s = [[Student alloc]init];
s.name = string;
s.name1 = string;
[string appendString:@"abc"];
NSLog(@"%@",string); 1234abc
NSLog(@"%@",s.name);1234abc
NSLog(@"%@",s.name1);1234
当熟悉使用copy和strong修饰时,系统自动生成的set方法就如下面这样,name1的源字符串是可变的,copy是深拷贝。_name1和源string是互不影响的。
@implementation Student
- (void)setName1:(NSString *)name1{
_name1 = name1;
}
- (void)setName1:(NSString *)name1{
_name1 = [name1 copy];
}
@end
通过以上的例子可以知道ARC机制下,对字符串对象属性的修饰,你可以用strong也可以用copy,一般情况下效果是一样的,strong的性能更高一些。只有在源字符串是可变时,不合理使用strong也许会发生一些不期待的效果。
使用建议:一般情况下作为数据模型的属性,属性的值一般都是直接源于网络数据的字符串,不会是可变的。使用strong一般不会有问题的。其它的情况下,像以上的用可变的字符串作为源字符串也是极少的,因此大胆放心的使用strong,某种特殊情况你必须使用copy!
深拷贝和浅拷贝
三、block的copy
- 没有访问auto变量,block的类型是NSGlobalBlock
- 访问了auto变量,block的类型是_NSStackBlock,但是在ARC环境下,block被强指针指向时,编译器会根据情况自动将栈上的block复制到堆上。
ARC下block属性的建议写法
@property (strong, nonatomic) void (^block)(void);
@property (copy, nonatomic) void (^block)(void);
参考:block的底层原理