iOS淺拷貝和深拷貝

淺拷貝:拷貝指向原來對(duì)象的指針,使原對(duì)象的引用計(jì)數(shù)+1,可以理解為創(chuàng)建了一個(gè)指向原對(duì)象的新指針而已,并沒有創(chuàng)建一個(gè)全新的對(duì)象。


淺拷貝.png
NSString *str1 = @"str1";
NSString *str2 = [str1 copy];
NSLog(@"\nstr1 = %@ str1P = %p \n str2 = %@ str2P = %p", str1, str1, str2, str2);

/*輸出結(jié)果
str1 = str1 str1P = 0x104d75180
str2 = str1 str2P = 0x104d75180
*/

深拷貝:拷貝出和原來僅僅是值一樣,但是內(nèi)存地址完全不一樣的新的對(duì)象,創(chuàng)建后和原對(duì)象沒有任何關(guān)系。


深拷貝.png
NSMutableString *mStr1 = [NSMutableString stringWithString:@"123"];
NSMutableString *mStr2 = [mStr1 mutableCopy];
NSLog(@"\n mStr1 = %@ mStr1P = %p \n mStr2 = %@ mStr2P = %p", mStr1, mStr1, mStr2, mStr2);
/*輸出結(jié)果
       mStr1 = 123 mStr1P = 0x6000004460c0
       mStr2 = 123 mStr2P = 0x600000446420
*/
開辟了新的內(nèi)存空間
可變對(duì)象NSMutableString
- (void) mutableNSStringTest
{
    NSMutableString *mstr1 = [NSMutableString stringWithString:@"test002"];
    
    NSMutableString *mstr2 = [mstr1 copy];
    
    //[str2 appendString:@"test"]; //copy返回的是不可變對(duì)象,mstr2不能被修改,因此會(huì)發(fā)生崩潰
    
    NSMutableString *mstr3 = [mstr1 mutableCopy];
    [mstr3 appendString:@"modify"];
    
    NSLog(@"mstr1:%p - %@ \r\n",mstr1,mstr1);
    NSLog(@"mstr2:%p - %@ \r\n",mstr2,mstr2);
    NSLog(@"mstr3:%p - %@ \r\n",mstr3,mstr3);
}

2017-07-20 18:14:35.789 beck.wang[1433:180881] mstr1:0x610000075e40 - test002 
2017-07-20 18:14:35.790 beck.wang[1433:180881] mstr2:0xa323030747365747 - test002 
2017-07-20 18:14:35.790 beck.wang[1433:180881] mstr3:0x610000074480 - test002modify

分析:mstr1、mstr2、mstr3 地址都不同,NSMutableString對(duì)象copy與mutableCopy都是深拷貝,且copy返回的對(duì)象是不可變對(duì)象。
總結(jié)一波:copy不可變對(duì)象時(shí)是淺拷貝,copy可變對(duì)象時(shí)是深拷貝,mutableCopy是深拷貝

再來看一段代碼
    NSString *str1 = @"str1";
    NSString *str2 = [str1 copy];
    
    str1 = @"asdf";

    NSLog(@"\nstr1 = %@ str1P = %p \n str2 = %@ str2P = %p", str1, str1, str2, str2);

    /*輸出結(jié)果,修改str2 同理
       str1 = asdf str1P = 0x10776b1a0
       str2 = str1 str2P = 0x10776b180
     */

這里不是說copy是淺拷貝嗎?str1 和 str2 指向同一個(gè)內(nèi)存空間,str1變化,str2的值也會(huì)變化。

但是copy還有它的特點(diǎn):

修改源對(duì)象的屬性和行為,不會(huì)影響副本對(duì)象
修改副本對(duì)象的屬性和行為,不會(huì)影響源對(duì)象

自定義類實(shí)現(xiàn)copy的步驟:

(1)遵守NSCoping協(xié)議
(2)實(shí)現(xiàn)copyWithZone方法。//參數(shù)zone基本不用,它的意思是指定該方法從始至終都在某一個(gè)區(qū)域分配內(nèi)存
(所有copy最終都會(huì)調(diào)用這個(gè)方法)
{
  //方法內(nèi)部進(jìn)行以下操作
  //(1)實(shí)例化對(duì)象
  A* a = [A alloc ]init]; //一般正規(guī)寫法是[[self.class alloc] init] 因?yàn)檫@樣子類也可以復(fù)用該方法
  //(2)給屬性賦值
  a.xx = xx;
  //(3)返回新對(duì)象
  return a;
}

#import <Foundation/Foundation.h>

/*
 創(chuàng)建一個(gè)Teacher類,并讓該類實(shí)現(xiàn)copy方法
 */

//1.遵守NSCopying協(xié)議
@interface Teacher : NSObject<NSCopying>
@property(nonatomic,copy)NSString* name;
//2.實(shí)現(xiàn)copyWithZone方法;
-(id)copyWithZone:(NSZone *)zone;
@end
#import "Teacher.h"

@implementation Teacher
//實(shí)現(xiàn)copyWithZone方法
-(id)copyWithZone:(NSZone *)zone
{
    Teacher* teacher = [[self.class alloc]init];
    teacher.name = self.name;
    return teacher;
}
@end
@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    Teacher* teacher = [[Teacher alloc]init];
    teacher.name = @"我是園丁";
    
    Teacher* teacher1 = [teacher copy];
   
    NSLog(@"teacher:%p-%@",teacher,teacher.name);
    NSLog(@"teacher1:%p-%@",teacher1,teacher1.name);
}

運(yùn)行結(jié)果:
2015-08-15 16:41:07.821 copy的那些事[1779:148657] teacher:0x7fd750d13ce0-我是園丁
2015-08-15 16:41:07.822 copy的那些事[1779:148657] teacher1:0x7fd750d13cf0-我是園丁

上面代碼如果沒有實(shí)現(xiàn)NSCopying協(xié)議,-[Person copyWithZone:]: unrecognized selector sent to instance 0x60000022b6a0

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對(duì)...
    cosWriter閱讀 11,665評(píng)論 1 32
  • 深拷貝和淺拷貝這個(gè)問題在面試中常常被問到,而在實(shí)際開發(fā)中,只要稍有不慎,就會(huì)在這里出現(xiàn)問題。尤其對(duì)于初學(xué)者來說,我...
    weyan閱讀 563評(píng)論 0 1
  • 對(duì)于不可變的集合類對(duì)象進(jìn)行 copy 操作,只是改變了指針,其內(nèi)存地址并沒有發(fā)生變化;進(jìn)行 mutableCopy...
    魔性佛心閱讀 753評(píng)論 0 0
  • 前一段時(shí)間課設(shè)時(shí),寫了個(gè)分頁插件的半成品,最后并沒有派上用場,然而今天無意間看到了,就改造了一下,算是比較完整的插...
    簡心豆閱讀 418評(píng)論 0 2
  • 說實(shí)話并沒有完全看懂。 盡管ta的語言是輕松活潑的,他所描繪的世界也是一個(gè)奇幻的,充滿想象力的世界。 好像作者在跟...
    瘋狂老李閱讀 1,591評(píng)論 10 12

友情鏈接更多精彩內(nèi)容