• iOS之strong和copy


    深拷贝和浅拷贝

        深拷贝和浅拷贝主要是对类类型而言的,浅拷贝就是指针拷贝,深拷贝是对象拷贝。

    property的strong和copy

       在接触iOS程序时经常会看到程序某些类类型属性被strong修饰,某些被copy修饰,刚开始接触时有些疑惑,后来不知咋地形成了这样的观念,对于mutable类型,用copy修饰,对于immutable类型,用strong修饰,现在看来这个大大地错了。

       创建属性是一件机械化的工作:对于一般的属性,你会将它们声明为 nonatomic。默认情况下,对象属性是strong的,标量属性是assign的。但是有一个例外,就是对于具有可变副本的属性,我们倾向于将其声明为 copy。比如说,name属性的类型是NSString,有可能有人创建了一个Person对象,并且给这个属性赋了一个NSMutableString的名字值。然后过了一会儿,这个可变字符串被变更了。如果我们的属性不是copy而是strong的话,随着可变字符串的改变,我们的Person对象也将发生改变,这不是我们希望发生的。对于类似数组或者字典这样的容器类来说,也是这样的情况。

    简单来说,对于被strong修饰property,在对其赋值时,并不是真正拷贝,而只是将右值的retain count加1,将左值的指针改为右值(也是一个指针)所指向的地址,直观来看,即赋值后左值和右值的地址值是一样一样的,即浅拷贝;
    但对于被copy所修饰的property且它遵循NSCopying协议,在为property赋值时,赋值语句不会保留新值(变量不会随可变字符串的改变而改变),直观来看,赋值后左值和右值的地址值可能不同,也即“赋值语句可能是深拷贝,也可能是浅拷贝”;
    P.S:这里为什么说“可能”呢?下文会对这个问题进行阐述。
    P.S:对于属性的赋值,单纯理解为浅拷贝或深拷贝操作是不对的,因为还会改变retain count的值(对于浅拷贝而言)。

    举个栗子:

    // 两个属性,前者用copy修饰,后者用strong修饰
    @property (nonatomic, copy) NSString *firstName;
    @property (nonatomic, strong) NSString *lastName;
    	
    NSMutableString *str1 = [NSMutableString stringWithString:@"不坏"];
    self.firstName = str1;		// 赋值
    // 打印左值和右值的地址值
    NSLog(@"str1 addr: 0x%lx", str1);
    NSLog(@"self.first addr: 0x%lx", self.firstName);
    	
    NSLog(@"");
    	
    NSMutableString *str2 = [NSMutableString stringWithString:@"张"];
    self.lastName = str2;		// 赋值
    // 打印左值和右值的地址值
    NSLog(@"str2 addr: 0x%lx", str2);
    NSLog(@"lastName addr: 0x%lx", self.lastName);
    

    打印结果是:

    str1 addr: 0x7967f580
    self.first addr: 0x7967f1d0
    	
    str2 addr: 0x7967f460
    lastName addr: 0x7967f460
    

     显然,对于用copy修饰的firstName,其赋值所采用的方式是深拷贝;对于用strong修饰的lastName,赋值方式是浅拷贝。

         回过头来解释上述的“可能”。

         其实很简单,对于赋值语句self.firstName = str1;(firstName被copy修饰),如果右值str1是mutable,则这条语句处理的方式是深拷贝。因为如果str1是mutable,并且执行浅拷贝的话,这就意味着如果str1改变了,则self.firstName也会跟着改变,这是我们不希望的,所以执行深拷贝时合理的;如果右值str1是immutable,则赋值语句所处理的方式依然是浅拷贝,因为反正str1不会再发生改变了,对self.firstName值不会有意想不到的影响,此时进行深拷贝有些浪费。

    P.S:Objective-C的这种设计理念略显啰嗦,比较智能的处理方法是当str1改变时,彼时再进行深拷贝处理,很多现代语言都是这么弄的,譬如Python。

    总结:property的关键字copy的本意是为了保护“immutable属性在被mutable右值对象赋值后不被右值之后可能发生的改变所影响”,而对mutable属性,则不存在这样的问题。

  • 相关阅读:
    POJ-2378 Tree Cutting
    ZOJ-3870 Team Formation
    POJ-1741 Tree (树上点分治)
    POJ-3107 Godfather
    HDU-3586 Information Disturbing(树形DP+删边)
    POJ 2796 (单调栈 + 前缀和)
    POJ 3250(单调栈)
    ATCoder 116 D (思维+贪心+栈)
    POJ2528 (离散化+线段树)
    HDU 2795(思维+线段树)
  • 原文地址:https://www.cnblogs.com/FightingLuoYin/p/4403083.html
Copyright © 2020-2023  润新知