iOS copy/strong作为修饰词对属性值的影响

最近开发遇到的一个问题,就是copy和strong作为属性的修饰词的区别,看了好多文章,没有几篇能够讲的很明白的,所以自己就梳理了一编。

第一步:

定义个不可变的对象,分别用copy和strong来作为修饰词

@property(nonatomic,strong) NSArray *strongArr;

@property (nonatomic,copy) NSArray *copyarr;

下面就来看看他们的区别

首先我们定义一个可变的对象,先来看赋值操作

NSMutableArray *arr = [NSMutableArray new];

[arr addObject:@1];

_strongArr = arr;

_copyarr = arr;

[arr addObject:@2];

打印结果:

 arr内存地址及指针指向:0x600002ebf030,0x7ffee4472158,

 _strongArr:内存地址及指针指向:0x600002ebf030,0x7fcad6405080,

_copyarr:内存地址及指针指向:0x600002ebf030,0x7fcad6405088,

从内存地址来看无论是copy还是strong修饰的对象同属同一内存地址,所以对arr的值进行修改他们都会改变即使是把arr赋给不可变的对象后;因为指针不同但是指向的内存地址都是一样的;

再来想一个问题如果把_strongArr和_copyarr换成self.xxx的形式结果还是一样吗?

 self.strongArr= arr;        self.copyarr= arr;      [arr addObject:@2];

打印结果:

 arr内存地址及指针指向:0x6000022526a0,0x7ffee006b158,

arr数组里面的元素( 1,    2)

 self.strongArr:内存地址及指针指向:0x6000022526a0,0x7f85a5f053d0,

strongArr数组里面的元素( 1, 2)

 self.copyarr:内存地址及指针指向:0x600002e2bb00,0x7f85a5f053d8,

copyarr数组里面的元素( 1)

可以看到从打印出来的数据可以看到对self.strongArr和 self.copyarr赋值后 ,再对原始数组arr进行操作后,copy修饰的属性这次内存地址发生了变化,是个新的内存地址,所以数组里面的参数没有变化,为什么呢,后面讲解。

再看看可变数组:

@property(nonatomic,strong) NSMutableArray *strongMutableArr;

@property (nonatomic,copy) NSMutableArray *copymutablearr;

再看看copy和strong修饰的可变对象赋值操作

 _strongMutableArr= arr;

  _copymutablearr = arr;

[arr addObject:@2];

打印结果:

 arr内存地址及指针指向:0x600001d84a50,0x7ffee8116158,

arr数组里面的元素(

    1,

    2

)

strongMutableArr:内存地址及指针指向:0x600001d84a50,0x7fd81bd03ac0,_

strongMutableArr数组里面的元素(

    1,

    2

)

_copymutablearr:内存地址及指针指向:0x600001d84a50,0x7fd81bd03ac8,

copymutablearr数组里面的元素(

    1,

    2

)

和不可变的对象执行结果是一样的,都是在同一个内存地址,那么问题来了,我可以对copymutablearr这个数组进行操作吗?

来试一下:

 [_copymutablearr addObject:@"这是copy修饰的可变数组添加的元素"];

打印结果:

arr数组里面的元素(

    1,

    2,

    "\U8fd9\U662fcopy\U4fee\U9970\U7684\U53ef\U53d8\U6570\U7ec4\U6dfb\U52a0\U7684\U5143\U7d20"

)

strongMutableArr数组里面的元素(

    1,

    2,

    "\U8fd9\U662fcopy\U4fee\U9970\U7684\U53ef\U53d8\U6570\U7ec4\U6dfb\U52a0\U7684\U5143\U7d20"

)

copymutablearr数组里面的元素(

    1,

    2,

    "\U8fd9\U662fcopy\U4fee\U9970\U7684\U53ef\U53d8\U6570\U7ec4\U6dfb\U52a0\U7684\U5143\U7d20"

)

可见这3个数组只要有个一改变,都会发生改变,因为他们是在同一内存地址。

self.xxx=arr,打印结果和不可变的数组结果是一样的,self.XXX也是从新生成了一个新的内存地址;

[self.copymutablearr addObject:@"这是copy修饰的可变数组添加的元素"]; 

这时候对copy数组进行操作会崩溃掉,

问题来了为什么copy修饰的_xxx=arr就可以对_xxx进行操作,而self.xxx=arr对self.xxx进行操作就会崩溃呢;

看下面的数据


self.xxx=arr
_xxx=arr

从类型上可以看出用copy修饰的,self.xxx=arr的时候可变数组变成了nssingleobjetarryi类型,他是说明只有一个元素,也不是可变数组的类型,如果没有元素就是_NSArray0,而可变数组是_NSArrayM类型,无论有多少元素可变数组应该是_NSArayM标记;而且崩溃日志也提示没有找到addObject:这个方法,说明copy修饰时用self.xxx进行被赋值的话就变成了不可变数组,前提是self.xxx才会有影响;

再来看两张图


self.xxx= arr(可变数组)
_xxx=arr(可变数组)

当不可变数组被赋值的时候,self.xxx=arr,用strong和copy修饰时 类型是有区别的,而_xxx=arr,_xxx的类型是没有区别的,原数组是什么类型被赋值的类型是源类型;


从上面四张图可以得出结论;

strong修饰的无论是可变的还是不可变的对象,无论是self.xxx还是_xxx,被赋值的对象类型都指向了赋值的对象类型arr,也就是说他们都是在同一内存地址下面,有一个动的其它的也会动;

copy修饰时_xxx无论是可变的还是不可变的,效果和strong修饰的是一样的,都是在同一个内存地址,唯一不一样的就是使用self.xxx时,会开辟新的内存地址;

注:copy修饰时,_xxx=arr时是可以对_xxx进行操作的,但是self.xxx=arr就不能对self.xxx进行操作了,应为self.xxx变成了不可变的了;


为什么self.xxx用copy修饰进行赋值操作的时候会开辟一个新的内存地址呢?

因为self.xxx进行赋值操作的话会走setter方法,而用copy修饰setter方法里面会进行一次深copy 操作,所以self.语法会从新分配新的内存地址;

所以说平时开发过程中属性修饰词用copy的时候一定要注意self.语法会重新开辟新的线程,没有strong修饰更加便捷,开内存就意味着消耗,慎用!

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

推荐阅读更多精彩内容