為什么聲明NString氛什,NSArray等需要使用copy莺葫,使用strong有什么問題,深拷貝和淺拷貝枪眉,block為什么使用copy捺檬。

一、為什么@property聲明(NString贸铜,NSArray欺冀,NSDictionary)時需要使用copy,使用strong有什么問題萨脑。

  • 因為NString隐轩,NSArray,NSDictionary都有自己對應(yīng)的子類:NSMutableString渤早,NSMutableArray职车,NSMutableDictionary,而父類指針可以指向子類對象鹊杖,使用copy可以讓本對象不受外界(子對象)影響悴灵,無論給我傳入的是一個可變對象還是一個不可變對象,都能保證自身持有的是一個不可變副本骂蓖。
  • 使用strong時积瞒,如果這個屬性指向一個可變對象,修改可變對象時登下,這個屬性值也會被修改茫孔。

舉例說明:

定義兩個屬性string和array用strong修飾

@interface ViewController ()
@property (strong, nonatomic) NSString *string;
@property (strong, nonatomic) NSArray *array;
@end
  - (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分別被賦值子類可變對象mString和mArray,再分別修改mString和mArray導致string和array都被修改了被芳。
下面看看使用copy關(guān)鍵字后的結(jié)果:

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

viewDidLoad中的代碼不變缰贝,打印結(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能保證屬性不被子類對象修改時同時被修改畔濒。

二剩晴、深拷貝和淺拷貝

  • 深拷貝:內(nèi)容的拷貝
  • 淺拷貝:地址的拷貝

1、對非集合對象的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

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

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

2侵状、對集合對象的copy和mutableCopy

集合對象指的是NSArray赞弥,NSDictionary毅整,NSSet等類的對象。

- (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é)論集合對象的copy和mutableCopy和非集合對象相同的結(jié)果:

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

注意事項:
集合對象的深拷貝只是對象本身绽左,而集合對象的元素還是地址的拷貝毛嫉,即單層深拷貝:

- (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的第一個元素地址:%p,arrayMCopy的第一個元素地址:%p",array[0],arrayMCopy[0]);
    NSLog(@"mArray的第一個元素地址:%p,mArrayMCopy的第一個元素地址:%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的第一個元素地址:0x6180000548e0,arrayMCopy的第一個元素地址:0x6180000548e0
2017-06-03 11:08:52.383 測試Test[62621:7832878] mArray的第一個元素地址:0x6180000548e0,mArrayMCopy的第一個元素地址:0x6180000548e0

三、block為什么要使用copy

block使用copy是在MRC中延續(xù)下來的妇菱,在MRC下承粤,方法內(nèi)部的block是存放在棧區(qū),使用copy會將block拷貝到堆區(qū)闯团。
在ARC下編譯器會自動對block進行copy辛臊,因此我們使用copy或者strong的效果是一樣的。但是我們在ARC下繼續(xù)使用copy可以提醒我們編譯器會自動幫我們實現(xiàn)copy的操作房交。


參考鏈接:《招聘一個靠譜的 iOS》-參考答案上

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末彻舰,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子候味,更是在濱河造成了極大的恐慌刃唤,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,366評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件白群,死亡現(xiàn)場離奇詭異尚胞,居然都是意外死亡,警方通過查閱死者的電腦和手機帜慢,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,521評論 3 395
  • 文/潘曉璐 我一進店門笼裳,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人粱玲,你說我怎么就攤上這事躬柬。” “怎么了抽减?”我有些...
    開封第一講書人閱讀 165,689評論 0 356
  • 文/不壞的土叔 我叫張陵允青,是天一觀的道長。 經(jīng)常有香客問我卵沉,道長颠锉,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,925評論 1 295
  • 正文 為了忘掉前任偎箫,我火速辦了婚禮木柬,結(jié)果婚禮上皆串,老公的妹妹穿的比我還像新娘淹办。我一直安慰自己,他們只是感情好恶复,可當我...
    茶點故事閱讀 67,942評論 6 392
  • 文/花漫 我一把揭開白布怜森。 她就那樣靜靜地躺著速挑,像睡著了一般。 火紅的嫁衣襯著肌膚如雪副硅。 梳的紋絲不亂的頭發(fā)上姥宝,一...
    開封第一講書人閱讀 51,727評論 1 305
  • 那天,我揣著相機與錄音恐疲,去河邊找鬼腊满。 笑死,一個胖子當著我的面吹牛培己,可吹牛的內(nèi)容都是我干的碳蛋。 我是一名探鬼主播,決...
    沈念sama閱讀 40,447評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼省咨,長吁一口氣:“原來是場噩夢啊……” “哼肃弟!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起零蓉,我...
    開封第一講書人閱讀 39,349評論 0 276
  • 序言:老撾萬榮一對情侶失蹤笤受,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后敌蜂,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體箩兽,經(jīng)...
    沈念sama閱讀 45,820評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,990評論 3 337
  • 正文 我和宋清朗相戀三年章喉,在試婚紗的時候發(fā)現(xiàn)自己被綠了比肄。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,127評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡囊陡,死狀恐怖芳绩,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情撞反,我是刑警寧澤妥色,帶...
    沈念sama閱讀 35,812評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站遏片,受9級特大地震影響嘹害,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜吮便,卻給世界環(huán)境...
    茶點故事閱讀 41,471評論 3 331
  • 文/蒙蒙 一笔呀、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧髓需,春花似錦许师、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,017評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽搭幻。三九已至,卻和暖如春逞盆,著一層夾襖步出監(jiān)牢的瞬間檀蹋,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,142評論 1 272
  • 我被黑心中介騙來泰國打工云芦, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留俯逾,地道東北人。 一個月前我還...
    沈念sama閱讀 48,388評論 3 373
  • 正文 我出身青樓舅逸,卻偏偏與公主長得像纱昧,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子堡赔,可洞房花燭夜當晚...
    茶點故事閱讀 45,066評論 2 355

推薦閱讀更多精彩內(nèi)容