淺入深出的Copy和MutableCopy理解

拷貝的目的

拷貝出一個和原對象的相同的副本,互不影響post

舉個例子

NSString *a = [NSString stringWithFormat:@"abcabcabc"];
    NSString *b = [a copy];
    NSString *c = [a mutableCopy];
    
    NSLog(@"%@,%@,%@",a,b,c);
    NSLog(@"%p,%p,%p",a,b,c);	
複製代碼

輸出結果:ui

abcabcabc,abcabcabc,abcabcabc
0xf9f7789ebc9c00cc,0xf9f7789ebc9c00cc,0x6000011f7090
複製代碼

疑問

  • 爲何a 和b 地址同樣
    • 咱們思考一下,因爲a 爲不可變字符串,自己就是不能夠改變的。因此只須要拷貝一個新的指針去指向a指向的地址就能夠了。 而c是a mutableCopy得來的。由於變成NSMutableString 並且不影響以前的對象,因此要拷貝出一個新的內存空間。

因此這裏就引出一個概念spa

  • 深拷貝指針

    • 內容拷貝
    • 建立新對象
  • 淺拷貝code

    • 指針拷貝
    • 引用計數+1
  • 爲何淺拷貝要引入計數+1 由於a 和 b 指向同一個內存地址。 若是不引用計數+1,會形成[a release]的時候 a對應的空間引用計數爲0,形成釋放。而此時b 還在引用釋放的內存空間,就會產生壞內存訪問的崩潰現象orm

其餘拷貝對象同理

不可變copy 爲淺拷貝對象

注意

Tagged Pointer對象比較特殊。不用管理引用計數。內存

NSString *a = [NSString stringWithFormat:@"abc"];
  NSLog(@"a retainCount = %ld",[a retainCount]);

  NSString *b = [a copy];
  NSLog(@"a retainCount = %ld",[a retainCount]);

  NSString *c = [a mutableCopy];

  NSLog(@"%@,%@,%@",a,b,c);
  NSLog(@"%p,%p,%p",a,b,c);
複製代碼

結果字符串

2019-09-12 13:54:58.109757+0800 Copy MutableCopy[13700:49429440] a retainCount = -1
2019-09-12 13:54:58.109876+0800 Copy MutableCopy[13700:49429440] a retainCount = -1
2019-09-12 13:54:58.109989+0800 Copy MutableCopy[13700:49429440] abc,abc,abc
2019-09-12 13:54:58.110062+0800 Copy MutableCopy[13700:49429440] 0xd5e0520931336344,0xd5e0520931336344,0x6000038d3330
複製代碼

Tagged Pointed 能夠知道a b 爲Tagged Pointer 對象 想深刻了解的的能夠看一下。get

總結

NSString NSMutableString NSArray NSMutableArray NSDictionary NSMutableDictionary
copy 淺拷貝 深拷貝 淺拷貝 深拷貝 淺拷貝 深拷貝
mutableCopy 深拷貝 深拷貝 深拷貝 深拷貝 深拷貝 深拷貝
相關文章
相關標籤/搜索