zoukankan      html  css  js  c++  java
  • iOS 关键词assign、strong、copy、weak、unsafe_unretained

    关键词assign、strong、copy、weak、unsafe_unretained

    影响:

    • 是否开辟新的内存
    • 是否有引用计数增加

    strong

    指向并拥有该对象。其修饰的对象引用计数会 +1,该对象只要引用计数不为 0 就不会销毁,置为 nil 可以销毁它。
    一般用于修饰对象类型、字符串、集合类的可变版本NSMutable

    // .h 文件
    @property (nonatomic, strong) NSMutableArray * nArr;
    
    
    // .m 文件
    {
         NSMutableArray * mArr = [[NSMutableArray alloc] 
                                   initWithObjects:@"a", @"b", @"c", nil];
         
         self.nArr = mArr;   // setter方法赋值时,  指针拷贝(浅拷贝)
    
         [mArr addObject:@"d"];
         NSLog(@"%@  %p  %p", self.nArr, self.nArr, mArr);
    }
    
    //打印结果
    2018-10-16 19:29:27.550029+0800 Demo[64192:936916] (
         a,
         b,
         c,
         d
    )    0x60000005bc60     0x60000005bc60    // 地址相同
    

    copy

    调用该变量的setter进行赋值,会把对象(值)拷贝一份副本,再赋。两个指针指向不同的内存地址,持有两个不同的对象。另一个对象发生变化不影响本身。

    一般NSString、NSArray、NSDictionary 等 用 copy 修饰,因为有可能赋值一个可变类型的指针,此时能保证属性值不会受外界影响。

    // .h 文件
    @property (nonatomic, copy) NSArray * nArr;
    
    // .m 文件
    {
         NSMutableArray * mArr = [[NSMutableArray alloc] 
                                  initWithObjects:@"a", @"b", @"c", nil];
         self.nArr = mArr;   // setter方法赋值时,  内容拷贝(深拷贝)
    
         [mArr addObject:@"d"];
         NSLog(@"%@  %p  %p", self.nArr, self.nArr, mArr);
    }
    2018-10-16 19:27:27.678093+0800 Demo[63966:933713] (
         a,
         b,
         c
    )    0x60000024e070    0x60000024c960   // 地址不同
    

    自定义对象需要实现NSCoping 协议:

    - (instancetype)copyWithZone:(NSZone *)zone
    {
         AModel * model = [[[self class] allocWithZone:zone] init];
         model.title = self.title;
         model.desc = self.desc;
         return model;
    }
    

    对比:strong 、copy
    strong 的赋值是多个指针指向同一个地址,
    copy 的赋值是每次会在内存中赋值一份对象,指针指向不同的地址。

    • 在MRC下,block属性为什么要用copy来修饰?
      因为block在创建时,它的内存是分配在栈(stack)上的,而不是在堆(heap)上,栈内存可能被随时回收。本身的作于域属于创建时的作用域,一旦在创建时候的作用域外调用block,将导致程序崩溃。通过copy可以把block拷贝到堆,保证block的声明域外使用。
      在ARC下写不写都行,编译器会自动对block进行copy操作。

    assign

    主要用于修饰 基本数据类型 等非OC对象,如 NSIntegerCGFloat等。
    这些数值主要存在于中。

    可以用来修饰对象。但是!被assign修饰的对象在释放后,指针的地址没被置为nil,成为野指针。如果后续在分配对象到堆上的某块内存时,正好分到这块地址,程序就会crash。

    不管是 MRC 还是 ARC,使用 assign 时,都需要注意释放。

    weak

    指向 但不拥有该对象。其修饰的对象引用计数不会增加,属性所指的对象遭到摧毁时,值会清空。
    ARC 环境下一般用于修饰可能会引起循环引用的对象。
    delegate、xib 控件用 weak 修饰。

    在使用 delegate 时,需要注意:

    • MRC 下,使用 assign。
    • ARC 下,都建议使用 weak,防止出现循环引用。否则如果用assign,当页面销毁时,很可能出现 delegate 对象无效,导致程序 crash。

    unsafe_unretained

    与 weak 类型相似,但是销毁时不自动清空,容易形成野指针。

    对比:
    weak 引用的 OC 对象被销毁时,指针会被自动清空,不再指向销毁的对象,不会产生野指针错误;
    assign 修饰基本数据类型,内存在栈上由系统自动回收。修饰对象类型时,也可能存在野指针。


    @property、@dynamic 和 @synthesize

    @property

    @property = ivr + getter + setter
    编译器自动编写访问这些属性所需的方法。

    @dynamic

    告诉编译器不要自动创建实现属性所用的实例变量,也不要为其创建存取方法。即使编译器发现没有定义存取方法也不会报错,运行期会导致崩溃。

    @synthesize

    在类的实现文件里, 指定实例变量的名称。

    源地址

  • 相关阅读:
    HDU5120
    POJ 1062
    POJ 1086
    BestCoder 1st Anniversary (HDU 5311)
    HDU 5284
    Dylans loves sequence(hdu5273)
    day65 作业
    第三次小组分享 猴子补丁
    day59 csrf auth
    day58 cookie session 中间件
  • 原文地址:https://www.cnblogs.com/jiuyi/p/11551638.html
Copyright © 2011-2022 走看看