谈weak,strong, assign, retain,copy

这个话题是一个老生常谈的问题了,今天把这几种情况总结一下,如有不对,欢迎指出~

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不可以。
posted on 2017-11-09 16:50  Werido_G  阅读(132)  评论(0编辑  收藏  举报