zoukankan      html  css  js  c++  java
  • 谈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不可以。
  • 相关阅读:
    道路和航线
    Sorting It All Out
    Sightseeing Cows(0/1分数规划+Spfa判负环)
    【模板】缩点
    间谍网络
    Tarjan算法专练
    数论知识点总结
    博客迁移到博客园
    第一届CCPC河南省赛
    find程序实现
  • 原文地址:https://www.cnblogs.com/werido/p/7810243.html
Copyright © 2011-2022 走看看