為什么聲明NString拜秧,NSArray等需要使用copy枉氮,使用strong有什么問題聊替,深拷貝和淺拷貝惹悄,block為什么使用copy泣港。

一当纱、為什么@property聲明(NString坡氯,NSArray箫柳,NSDictionary)時(shí)需要使用copy滞时,使用strong有什么問題坪稽。

  • 因?yàn)镹String窒百,NSArray篙梢,NSDictionary都有自己對(duì)應(yīng)的子類:NSMutableString渤滞,NSMutableArray,NSMutableDictionary绪励,而父類指針可以指向子類對(duì)象疏魏,使用copy可以讓本對(duì)象不受外界(子對(duì)象)影響大莫,無論給我傳入的是一個(gè)可變對(duì)象還是一個(gè)不可變對(duì)象,都能保證自身持有的是一個(gè)不可變副本懈凹。
  • 使用strong時(shí)介评,如果這個(gè)屬性指向一個(gè)可變對(duì)象寒瓦,修改可變對(duì)象時(shí)杂腰,這個(gè)屬性值也會(huì)被修改。

舉例說明:

定義兩個(gè)屬性string和array用strong修飾

@interface ViewController ()
@property (strong, nonatomic) NSString *string;
@property (strong, nonatomic) NSArray *array;
@end

@implementation ViewController
 - (void)viewDidLoad {
    NSMutableString * mString = [NSMutableString stringWithString:@"123"];
    self.string = mString;
    [mString appendString:@"666"];
    NSLog(@"%@",self.string);
    
    NSMutableArray *mArray = [NSMutableArray arrayWithObjects:@1,@2,@3, nil];
    self.array = mArray;
    [mArray addObject:@6];
    NSLog(@"%@",self.array);
}

打印結(jié)果:

2017-06-02 17:43:22.440 測試Test[45671:7372719] 123666
2017-06-02 17:43:22.441 測試Test[45671:7372719] (
    1,
    2,
    3,
    6
)

這里的屬性string和array分別被賦值子類可變對(duì)象mString和mArray,再分別修改mString和mArray導(dǎo)致string和array都被修改了漓帅。
下面看看使用copy關(guān)鍵字后的結(jié)果:(所有代碼不變忙干,只是strong改成copy)
打印結(jié)果:

2017-06-02 17:48:32.583 測試Test[45795:7380495] 123
2017-06-02 17:48:32.583 測試Test[45795:7380495] (
    1,
    2,
    3
)

屬性string和array都沒有被修改。所以使用copy能保證屬性不被子類對(duì)象修改時(shí)同時(shí)被修改。

二暇韧、深拷貝和淺拷貝

  • 深拷貝:內(nèi)容的拷貝
  • 淺拷貝:地址的拷貝
1浓瞪、對(duì)非集合對(duì)象的copy和mutableCopy
- (void)viewDidLoad {
    [super viewDidLoad];
    
    NSString *string = @"123";
    NSString *stringCopy = [string copy];
    NSLog(@"string的地址:%p,stringCopy的地址:%p",string,stringCopy);
    NSMutableString *stringMCopy = [string mutableCopy];
    NSLog(@"stringMCopy的地址:%p",stringMCopy);
    
    NSMutableString * mString = [NSMutableString stringWithString:@"123"];
    NSString *mStringCopy = [mString copy];
    NSLog(@"mString的地址:%p,mStringCopy的地址:%p",mString,mStringCopy);
    NSMutableString *mStringMCopy = [mString mutableCopy];
    NSLog(@"mStringMCopy的地址:%p",mStringMCopy);

}

打印結(jié)果:

2017-06-03 10:22:58.643 測試Test[61063:7767634] string的地址:0x10d696078,stringCopy的地址:0x10d696078
2017-06-03 10:22:58.644 測試Test[61063:7767634] stringMCopy的地址:0x61000006a640
2017-06-03 10:22:58.644 測試Test[61063:7767634] mString的地址:0x61000006d040,mStringCopy的地址:0xa000000003332313
2017-06-03 10:22:58.644 測試Test[61063:7767634] mStringMCopy的地址:0x600000072200
2乾颁、對(duì)集合對(duì)象的copy和mutableCopy

集合對(duì)象指的是NSArray,NSDictionary湾盒,NSSet等類的對(duì)象毅人。

- (void)viewDidLoad {
    [super viewDidLoad];

    NSArray *array = @[@1, @2, @3, @4];
    NSArray *arrayCopy = [array copy];
    NSMutableArray *arrayMCopy = [array mutableCopy];
    NSLog(@"array的地址:%p,arrayCopy的地址:%p,arrayMCopy的地址:%p",array,arrayCopy,arrayMCopy);

    NSMutableArray *mArray = [NSMutableArray arrayWithObjects:@1, @2, @3, @4, nil];
    NSArray *mArrayCopy = [mArray copy];
    NSMutableArray *mArrayMCopy = [mArray mutableCopy];
    NSLog(@"mArray的地址:%p,mArrayCopy的地址:%p,mArrayMCopy的地址:%p",mArray,mArrayCopy,mArrayMCopy);

}

打印結(jié)果:

2017-06-03 10:50:14.247 測試Test[61941:7806421] array的地址:0x600000058090,arrayCopy的地址:0x600000058090,arrayMCopy的地址:0x600000057b50
2017-06-03 10:50:14.247 測試Test[61941:7806421] mArray的地址:0x6100000556c0,mArrayCopy的地址:0x610000055780,mArrayMCopy的地址:0x610000055870

可以得出結(jié)論集合對(duì)象的copy和mutableCopy和非集合對(duì)象相同的結(jié)果:

  • [immutableObject copy]是淺拷貝
  • [immutableObject mutableCopy]是深拷貝
  • [mutableObject copy]是深拷貝
  • [mutableObject mutableCopy]是深拷貝

注意事項(xiàng):
集合對(duì)象的深拷貝只是對(duì)象本身缔俄,而集合對(duì)象的元素還是地址的拷貝邀桑,即單層深拷貝:

- (void)viewDidLoad {
    [super viewDidLoad];
    
    NSMutableArray *mArray1 = [NSMutableArray arrayWithObjects:@2, @2, @3, @4, nil];
    
    NSArray *array = @[mArray1, @2, @3, @4];
    NSArray *arrayCopy = [array copy];
    NSMutableArray *arrayMCopy = [array mutableCopy];
    NSLog(@"array的地址:%p,arrayCopy的地址:%p,arrayMCopy的地址:%p",array,arrayCopy,arrayMCopy);

    NSMutableArray *mArray = [NSMutableArray arrayWithObjects:mArray1, @2, @3, @4, nil];
    NSArray *mArrayCopy = [mArray copy];
    NSMutableArray *mArrayMCopy = [mArray mutableCopy];
    NSLog(@"mArray的地址:%p,mArrayCopy的地址:%p,mArrayMCopy的地址:%p",mArray,mArrayCopy,mArrayMCopy);
    
    NSLog(@"array的第一個(gè)元素地址:%p,arrayMCopy的第一個(gè)元素地址:%p",array[0],arrayMCopy[0]);
    NSLog(@"mArray的第一個(gè)元素地址:%p,mArrayMCopy的第一個(gè)元素地址:%p",mArray[0],mArrayMCopy[0]);

}

打印結(jié)果:

2017-06-03 11:08:52.382 測試Test[62621:7832878] array的地址:0x618000054c70,arrayCopy的地址:0x618000054c70,arrayMCopy的地址:0x618000054cd0
2017-06-03 11:08:52.382 測試Test[62621:7832878] mArray的地址:0x600000056020,mArrayCopy的地址:0x600000055fc0,mArrayMCopy的地址:0x600000056080
2017-06-03 11:08:52.383 測試Test[62621:7832878] array的第一個(gè)元素地址:0x6180000548e0,arrayMCopy的第一個(gè)元素地址:0x6180000548e0
2017-06-03 11:08:52.383 測試Test[62621:7832878] mArray的第一個(gè)元素地址:0x6180000548e0,mArrayMCopy的第一個(gè)元素地址:0x6180000548e0

三令杈、block為什么要使用copy

block使用copy是在MRC中延續(xù)下來的跌榔,在MRC下僧须,方法內(nèi)部的block如果有被copy屬性修飾纲刀,且捕獲了外部變量担平,那么他會(huì)被copy到堆上;如果被assgin修飾的空另,且捕獲了外部變量,那么他是stack_block摄杂,是在棧上的;如果僅僅只是一個(gè)copy的屬性的block析恢,么有捕獲外部變量,它還是是global_block,它是在全局區(qū)泽篮。
在ARC下編譯器會(huì)自動(dòng)對(duì)block進(jìn)行copy柑船,因此我們使用copy或者strong修飾的效果是一樣的。但是我們?cè)贏RC下繼續(xù)使用copy可以提醒我們編譯器會(huì)自動(dòng)幫我們實(shí)現(xiàn)copy的操作亏拉。至于block是哪中類型的逆巍,他是在內(nèi)存的哪個(gè)區(qū)的锐极,和MRC下的是一樣的,要看block有木有引用外部變量肋层。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末槽驶,一起剝皮案震驚了整個(gè)濱河市鸳兽,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌全陨,老刑警劉巖衷掷,帶你破解...
    沈念sama閱讀 221,430評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異戚嗅,居然都是意外死亡雨涛,警方通過查閱死者的電腦和手機(jī)枢舶,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,406評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門替久,熙熙樓的掌柜王于貴愁眉苦臉地迎上來凉泄,“玉大人,你說我怎么就攤上這事蚯根。” “怎么了颅拦?”我有些...
    開封第一講書人閱讀 167,834評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵蒂誉,是天一觀的道長。 經(jīng)常有香客問我距帅,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,543評(píng)論 1 296
  • 正文 為了忘掉前任昔善,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘捕捂。我一直安慰自己袱院,他們只是感情好董栽,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,547評(píng)論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著潮剪,像睡著了一般分唾。 火紅的嫁衣襯著肌膚如雪弧蝇。 梳的紋絲不亂的頭發(fā)上折砸,一...
    開封第一講書人閱讀 52,196評(píng)論 1 308
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼去枷。 笑死怖辆,一個(gè)胖子當(dāng)著我的面吹牛是复,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播竖螃,決...
    沈念sama閱讀 40,776評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼淑廊,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了斑鼻?” 一聲冷哼從身側(cè)響起蒋纬,我...
    開封第一講書人閱讀 39,671評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎坚弱,沒想到半個(gè)月后蜀备,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,221評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡荒叶,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,303評(píng)論 3 340
  • 正文 我和宋清朗相戀三年碾阁,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片些楣。...
    茶點(diǎn)故事閱讀 40,444評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡脂凶,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出愁茁,到底是詐尸還是另有隱情蚕钦,我是刑警寧澤,帶...
    沈念sama閱讀 36,134評(píng)論 5 350
  • 正文 年R本政府宣布鹅很,位于F島的核電站嘶居,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏促煮。R本人自食惡果不足惜邮屁,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,810評(píng)論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望菠齿。 院中可真熱鬧佑吝,春花似錦、人聲如沸绳匀。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,285評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽疾棵。三九已至盗飒,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間陋桂,已是汗流浹背逆趣。 一陣腳步聲響...
    開封第一講書人閱讀 33,399評(píng)論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留嗜历,地道東北人宣渗。 一個(gè)月前我還...
    沈念sama閱讀 48,837評(píng)論 3 376
  • 正文 我出身青樓抖所,卻偏偏與公主長得像,于是被迫代替她去往敵國和親痕囱。 傳聞我的和親對(duì)象是個(gè)殘疾皇子田轧,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,455評(píng)論 2 359