在日常的編程中經(jīng)常會(huì)使用NSString褒繁,但是NSString到底是使用copy修飾還是使用strong進(jìn)行修飾呢?或者說(shuō)NSString什么時(shí)候使用copy
什么時(shí)候使用strong
呢何暇?
- 首先需要知道的是
copy
的作用温艇,當(dāng)我們使用copy
去修飾NSString的時(shí)候,就是想讓這個(gè)NSString不受外部的影響穴肘,比如說(shuō)self.a = b
蛾扇,當(dāng)b改變的時(shí)候攘烛,a不會(huì)受到影響還是原來(lái)的值魏滚,這樣保證了安全性
當(dāng)我們使用@property (nonatomic, copy) NSString *a;
并且進(jìn)行賦值self.a = b ;
- 如果b是一個(gè)不可變的變量镀首,例如NSString類型,這個(gè)時(shí)候其實(shí)是進(jìn)行了一次淺拷貝鼠次,也就是說(shuō)這個(gè)時(shí)候更哄,不管是strong還是copy屬性的對(duì)象芋齿,其指向的地址都是同一個(gè),即為b指向的地址成翩,在MRC環(huán)境下的效果都是使b指向的對(duì)象的引用計(jì)數(shù)+1觅捆;
- 如果b是一個(gè)可變的變量,例如NSMutableString 類型麻敌,這個(gè)時(shí)候就有所不同了栅炒,因?yàn)閏opy修飾的屬性會(huì)進(jìn)行一次深拷貝,也就是說(shuō)其會(huì)
創(chuàng)建一個(gè)新的對(duì)象
术羔,另外需要注意的是赢赊,這個(gè)copy屬性對(duì)象的類型始終是NSString,而不是NSMutableString级历,因此其是不可變的释移。;
當(dāng)我們使用@property (nonatomic, strong) NSString *a;
并且進(jìn)行賦值self.a = b ;
- 無(wú)論b是可變的類型或是不可變的類型寥殖,都不會(huì)創(chuàng)建一個(gè)新的對(duì)象玩讳,效果都是a指向了b指向的對(duì)象,在MRC環(huán)境下嚼贡,就是b指向的對(duì)象的引用計(jì)數(shù)+1
- 這種情況帶來(lái)了一個(gè)問(wèn)題熏纯,如果b為可變類型,并且b在外部進(jìn)行了一些修改粤策,這樣導(dǎo)致了a也會(huì)改變豆巨,不安全;另外掐场,如果b是一個(gè)可變的類型例如NSMutableString 類型往扔,那么,_a的類型實(shí)際上就是NSMutableString熊户,因?yàn)镹SString是NSMutableString的父類萍膛,這樣是沒(méi)有問(wèn)題的
總結(jié):
看了這么多那么到底什么時(shí)候使用copy
什么時(shí)候使用strong
呢?我的經(jīng)驗(yàn)是這樣的嚷堡,
- 當(dāng)你十分確定將要賦一個(gè)不變的值的時(shí)候用strong蝗罗,當(dāng)我們使用copy修飾a,進(jìn)行賦值的時(shí)候蝌戒,會(huì)對(duì)b進(jìn)行一個(gè)類型的判斷串塑,
if ([str isMemberOfClass:[str class]])
如果是不可變的類型就直接使用strong的策略,即指向b指向的對(duì)象進(jìn)行淺拷貝北苟,如果b是一個(gè)可變的類型桩匪,那么進(jìn)行一次深拷貝創(chuàng)建一個(gè)新的對(duì)象,試想一下友鼻,如果是一個(gè)你確定的不會(huì)變的值我們?yōu)槭裁催€需要進(jìn)行一次類型的判斷呢傻昙?使用strong能夠提升一定的性能闺骚; - 但是很多情況下我們并不能確定要賦的值b是什么類型的,所以我們還是使用copy來(lái)修飾妆档,這樣保證了安全性僻爽。