iOS-浅拷贝、深拷贝

1,180 阅读3分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动

本文同时参与「掘力星计划」,赢取创作大礼包,挑战创作激励金

通过问题看本质!!!

经常搞不清copy和mutableCopy的区别,copy和mutableCopy究竟是深拷贝还是浅拷贝。其实只要记住精髓,知道拷贝的目的,所有的问题都会引刃而解。

拷贝的目的

拷贝的目的:产生一个副本对象,跟原来的对象互不影响。

修改了源对象,不会影响副本对象。

修改了副本对象,不会影响源对象。

就好比我们电脑上有个readme.md文件,我们拷贝readme.md文件得到readme的副本.md文件。无论我们修改哪个文件,都不会影响另外一个文件。

浅拷贝、深拷贝

使用copy,是不可变拷贝,会产生不可变副本,使用mutableCopy,是可变拷贝,会产生可变副本。我们由拷贝又引申出了浅拷贝、深拷贝。

浅拷贝:指针拷贝,没有产生新对象,指针指向同一个对象。

深拷贝:内容拷贝,有产生新对象,指针指向不同一个对象。

不可变对象拷贝操作

void testString1()

{

    NSString *string1 = [[NSString alloc] initWithFormat:@"test---String"];

    NSString *string2 = [string1 copy]; // 浅拷贝,指针拷贝,没有产生新对象

    NSMutableString *string3 = [string1 mutableCopy]; // 深拷贝,内容拷贝,有产生新对象

    NSLog(@"%@ %@ %@", string1, string2, string3);

    NSLog(@"%p %p %p", string1, string2, string3);
    
    //打印结果: test---String test---String test---String 
    //打印结果: 0x10063b2b0 0x10063b2b0 0x10063ad80 
}
copy操作

不可变对象(NSString *)string1,调用copy方法,不会产生新对象,是浅拷贝

因为string1是不可变对象,不能进行修改。

copy之后得到的也是不可变对象,既然2个都是不可变对象,那干脆指向同一个对象,还能节省内存。

所以不可变对象copy操作,是浅拷贝。

mutableCopy操作

不可变对象(NSString *)string1,调用mutableCopy方法,会产生新对象,是深拷贝

因为string1是不可变对象,不能进行修改。

mutableCopy之后得到的也是可变对象,既然是可变对象,那它就可以修改。而修改之后又不能影响原来的对象,这是拷贝的宗旨。所以mutableCopy会产生新对象,这样无论怎么修改都不会影响源对象。

所以不可变对象mutableCopy操作,是深拷贝。

可变对象拷贝操作

void testString2()

{
    NSMutableString *mutableString1 = [[NSMutableString alloc] initWithFormat:@"test-mutableString"]; 

    NSString *mutableString2 = [mutableString1 copy]; // 深拷贝

    NSMutableString *mutableString3 = [mutableString1 mutableCopy]; // 深拷贝

    NSLog(@"%@ %@ %@", mutableString1, mutableString2, mutableString3);

    NSLog(@"%p %p %p", mutableString1, mutableString2, mutableString3);

    //打印结果: test-mutableString test-mutableString test-mutableString 
    //打印结果: 0x1006114b0 0x100611500 0x100605d60
}
copy操作

可变对象(NSMutableString *)mutableString1,调用copy方法,会产生新对象,是深拷贝

因为mutableString1是可变对象,可以进行修改。

copy之后得到的也是不可变对象,不可以修改。所以一个可以修改,一个不可修改,为了让它们互不干扰,也必定会产生新对象。

所以可变对象copy操作是深拷贝。

mutableCopy操作

可变对象(NSMutableString *)mutableString1,调用mutableCopy方法,会产生新对象,是深拷贝

因为mutableString1是不可变对象,可以进行修改。

mutableCopy之后得到的也是可变对象,既然是可变对象,那它就可以修改。

它们2个都可以修改,为了让它们互不干扰,也必定会产生新对象。

所以可变对象mutableCopy操作,是深拷贝。

总结

  • 不可变对象copy操作,是浅拷贝

  • 不可变对象mutableCopy操作,是深拷贝

  • 可变对象copy操作,是深拷贝

  • 可变对象mutableCopy操作,是深拷贝