这个话题是一个老生常谈的问题了,今天把这几种情况总结一下,如有不对,欢迎指出~
weak-strong
copy
修饰字符串strong与copy的区别
1、当字符串用strong修饰时:
PersonModel.h @property(nonatomic,strong)NSString *name; MainViewController.m NSMutableString *mString = [[NSMutableString alloc]initWithString:@"Tom"]; PersonModel *model = [[PersonModel alloc]init]; model.name = mString; [mString setString:@"LiMing"]; NSLog(@"%@",model.name); NSLog(@"%p----%p",mString,model.name);
2017-11-09 15:45:48.762989+0800 测试推送[13801:302915] LiMing 2017-11-09 15:45:48.763167+0800 测试推送[13801:302915] 0x604000456f80----0x604000456f80
1、当字符串用copy修饰时:
PersonModel.h @property(nonatomic,copy)NSString *name; MainViewController.m NSMutableString *mString = [[NSMutableString alloc]initWithString:@"Tom"]; PersonModel *model = [[PersonModel alloc]init]; model.name = mString; [mString setString:@"LiMing"]; NSLog(@"%@",model.name); NSLog(@"%p----%p",mString,model.name);
2017-11-09 16:09:44.432201+0800 测试推送[13943:319792] Tom 2017-11-09 16:09:44.432391+0800 测试推送[13943:319792] 0x60000044e8e0----0xa000000006d6f543
根据代码的运行结果我们发现,当用copy修饰时,属性是不会随着mString的变化而变化的,内存地址也不一样,所以:
- 当使用strong时,字符串的retain计数将增加1,属性与字符串指向同一个内存地址。这意味着任何指向这个内存地址的变量都可改变这个值;
- 当使用copy时,系统会为name新开辟一个空间存储,无论mString怎么改变name都不会改变。
代理为啥要用weak修饰?
weak-strong
weak
:指明该对象并不负责保持delegate这个对象,delegate这个对象的销毁由外部控制
- strong: 该对象强引用delegate,外界不能销毁delegate对象,会导致循环引用(Retain Cycles)
weak-assign
weak
: 不对引用计数操作,使用之后会把对象置为nil,不会产生野指针;- strong: 不对引用计数操作,使用之后如果没有置为nil,可能就会产生野指针;
block为啥要用copy修饰?
- block其实就是一个代码块,把你想要执行的代码封装在这个代码块里,等到需要的时候再去调用。那block也是OC对象。
-
block本身是像对象一样可以retain,和release。但是,block在创建的时候,它的内存是分配在栈(stack)上,而不是在堆(heap)上。他本身的作于域是属于创建时候的作用域,一旦在创建时候的作用域外面调用block将导致程序崩溃。使用retain也可以,但是block的retain行为默认是用copy的行为实现的,因为block变量默认是声明为栈变量的,为了能够在block的声明域外使用,所以要把block拷贝(copy)到堆,所以说为了block属性声明和实际的操作一致,最好声明为copy。
- 在ARC下,要避免block出现循环引用,经常会:__weak typedof(self) weakSelf = self; __strong typedof(self) strongSelf = weakSelf;
__block和__weak有什么区别?
__block
不管是ARC还是MRC模式下都可以使用,可以修饰对象,还可以修饰基本数据类型。__weak
只能在ARC模式下使用,也只能修饰对象(NSString),不能修饰基本数据类型(int)。__block
对象可以在block中被重新赋值,__weak
不可以。