iOS 的strong和copy

之前有过一篇文章关于iOS 属性的 iOS指示符 assign、copy、retain、strong、weak,之后看了一遍有总结了一下:

NSString 选 Strong 还是copy?

1、现分别创建NSString 的strong 和 copy 两个属性


@property(nonatomic, strong) NSString *age1;
@property(nonatomic, copy) NSString *age2; 

2、创建一个NSString 常量,赋值给上面的age1和age2两个属性。

    NSString *age = @"11";
    NSLog(@"age:  %@ - %p", age, age);
    self.age1 = age;
    self.age2 = age;
    NSLog(@"age1: %@ - %p", self.age1, self.age1);
    NSLog(@"age2: %@ - %p", self.age2, self.age2);
    
    NSString *ageOther = [age stringByAppendingString:@"20"];
    NSLog(@"age:  %@ - %p", age, age);
    NSLog(@"ageother:  %@ - %p", ageOther, ageOther);
    NSLog(@"age1: %@ - %p", self.age1, self.age1);
    NSLog(@"age2: %@ - %p", self.age2, self.age2);

3、结果:

 age:  11 - 0x108f28078              
 age1: 11 - 0x108f28078              
 age2: 11 - 0x108f28078              
 age:  11 - 0x108f28078              
 ageother:  1120 - 0x600000255000    
 age1: 11 - 0x108f28078              
 age2: 11 - 0x108f28078              

分析:
我们可以发现,给age1和age2 赋值一个不可变的字符串的时候,都进行了浅拷贝,只拷贝了指针地址,使age、age1、age2都指向同一个地址,在对age进行增加字符串时,因为age是不可变字符串,所以age没有变化,于是age1、age2都没有变化。

总结:声明String和copy属性的String被不可变String赋值时,没有变化,都是浅拷贝,都不会发生变化。

1、现分别创建NSString 的strong 和 copy 两个属性


@property(nonatomic, strong) NSString *str1;
@property(nonatomic, copy) NSString *str2;

2、创建一个NSMutableString 可变字符串,赋值给上面的str1和str2两个属性。

    NSMutableString *name = [[NSMutableString alloc] initWithString:@"Alex"];
    NSLog(@"name : %@ - %p", name, name);
    self.str1 = name;
    self.str2 = name;
    NSLog(@"str1 %@ - %p", self.str1, self.str1);
    NSLog(@"str2 %@ - %p", self.str2, self.str2);
    
    [name appendString:@"Le"];
    
    NSLog(@"str1 %@ - %p", self.str1, self.str1);
    NSLog(@"str2 %@ - %p", self.str2, self.str2);

3、结果:

 name : Alex - 0x604000255cc0       
 str1 : Alex - 0x604000255cc0       
 str2 : Alex - 0xa00000078656c414   

 str1 : AlexLe - 0x604000255cc0     
 str2 : Alex - 0xa00000078656c414              

分析:
我们可以看出在用可变字符串给属性变量赋值时,strong的str1 对name进行浅拷贝,只拷贝了地址,所以str1和name指向同一个地址,而copy 的 str2 对name 进行了深拷贝,str2将name复制到一个新空间内。
当我们对name增添时,此时我们可以看到和name指向相同的str1的内容改变了,而新开辟空间的str2却还保持原来的值。

总结:

声明String和copy属性的String被可变的NSMutableString name赋值时,strong类型的会随可变字符串的变化而变化,但是copy类型的却不会随可变字符串的变化而变化。所以当属性被不可变的字符串赋值时,strong和copy没有区别;当属性被可变字符串赋值时,copy不会被修改,而strong会被修改。综上所述,copy更简单、安全。

NSArray 和 NSMutableArray 是 copy 还是 strong?

1、NSMutableArray 不能被copy修饰,因为以后对数组的增删改操作在copy之后数组都会变成不可变数组,对其进行增删改都将crash。

      @property (copy) NSMutableArray * a;
      NSMutableArray* b = [NSMutableArray array];
      a = b;

等同于

       @property (strong) NSMutableArray * a;
       NSMutableArray* b = [NSMutableArray array];
       a = [b copy];

a在被copy之后就变成了不可变数组NSArray了。

2、NSMutableArray 被strong修饰,在赋值的时候就如上面说的那样会指向同一个地址,被定义的属性也不会改变。

@property(nonatomic, strong) NSMutableArray *arrayA;
@property(nonatomic, copy) NSMutableArray *arrayB;
    NSMutableArray *arrayC = [NSMutableArray array];
    NSLog(@"arrayC.class: %@ - %p", arrayC.class, arrayC);
    self.arrayA = arrayC;
    self.arrayB = arrayC;
    NSLog(@"arrayA.class: %@ - %p", _arrayA.class, _arrayA);
    NSLog(@"arrayB.class: %@ - %p", _arrayB.class, _arrayB);
    
    [self.arrayA removeAllObjects];
    [self.arrayB removeAllObjects];

结果:

arrayC.class: __NSArrayM - 0x604000251220                                                                                                                                   
arrayA.class: __NSArrayM - 0x604000251220                                                                                                                                   
arrayB.class: __NSArray0 - 0x6000000021a0                                                                                                                                   
-[__NSArray0 removeAllObjects]: unrecognized selector sent to instance 0x6000000021a0                                                                                       
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArray0 removeAllObjects]: unrecognized selector sent to instance 0x6000000021a0' 

分析:我们可以看到arrayA 和 arrayC的指向同一个地址,且类型都是mutable的,arrayB的类型发生了改变变成不可变的类型。所以,NSMutableArray被copy修饰之后就变成不可变的,在对其操作时容易crash。
而NSArray被copy或者strong修饰的时候和NSString相同。

1、当arrayA被strong修饰,且被可变数组赋值,可变数组arrayMB改变,被strong修饰属性arrayA也做同样修改,arrayA和arrayMB指向的地址相同;
2、当array被copy修饰,且被可变数组赋值,可变数组arrayMB改变,被copy修饰的属性arrayB没有被修改,因为arrayB深拷贝arrayMB,arrayB和arrayMB在两个内存块中。
3、不管array被strong、copy修饰,只要被不可变数组赋值,此时都指向同一个内存地址。

NSMutable可变的类型最好不要使用copy,不可变的看需不需要被修改,在看strong 和 copy的定义。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,340评论 5 467
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,762评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,329评论 0 329
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,678评论 1 270
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,583评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 47,995评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,493评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,145评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,293评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,250评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,267评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,973评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,556评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,648评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,873评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,257评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,809评论 2 339

推荐阅读更多精彩内容

  • 1.ios高性能编程 (1).内层 最小的内层平均值和峰值(2).耗电量 高效的算法和数据结构(3).初始化时...
    欧辰_OSR阅读 29,276评论 8 265
  • ​ 前段时间,在公司跟几个同事出去吃饭,饭间聊到各种蔬菜,继而聊到菜园,聊到小时候的事情。然后就想起小时候在...
    3319f86f7c7e阅读 319评论 3 2
  • 一层月牙白,三丝清凉风,在一个平平常常的早晨,玉兰花开了。此时有点寒,此地有朵花,花瓣如凝雪,花香长精神。...
    冰夫阅读 291评论 0 2
  • 从前,江西有个三同年(俗称老庚),他们自结为拜把兄弟之后,彼此相敬如宾,和睦相处,关系堪称其乐融融。 一天,正值三...
    镇南方良金阅读 469评论 0 1
  • 1. 继承 继承注意事项 子类继承父类所有变量和方法; 继承是单向的, 子类所有成员变量和方法 没有父类的类称为根...
    李小六_阅读 2,373评论 0 6