IOS illustrated with you to understand deep copy and shallow copy

Source: Internet
Author: User

I. Concept and SUMMARY

1. Shallow copy

A shallow copy is a copy of the memory address, so that the target object pointer and source object point to the same piece of memory space, when the memory is destroyed, a few pointers to this memory need to be redefined to use, otherwise it will become a wild pointer.

A shallow copy is a pointer to the original object, so that the reference count of the original object is +1, which can be understood as creating a new pointer to the original object, and not creating a completely new object.

2. Deep copy

Deep copy refers to the specific contents of the Copy object, and the memory address is self-allocated, after the end of the copy, two objects, although the value is the same, but the memory address is not the same, two objects do not affect each other, non-interference.

A deep copy is a new object that copies the same value as the original, but has a completely different memory address, and does not have any relationship with the original object after it is created.

3. Summary:

A deep copy is a copy of the content, and a shallow copy is a pointer copy. The essential difference is:

    • Whether to open a new memory address
    • Whether to affect the reference count of memory addresses
Second, example analysis

Deep copy and shallow copy are more complex in iOS, involving the copy and mutablecopy of containers and non-containers, mutable and immutable objects. The following examples are used to analyze each:

1 . Copy and Mutablecopy of non-collection objects

1.1 Immutable Objects NSString

-(void) nomutablensstringtest{    nsstring *str1 = @ "test001";        nsmutablestring *STR2 = [str1 copy];    Copy returns an immutable object, STR2 cannot be modified, so a crash    //[str2 appendstring:@ "test" will occur;        nsmutablestring *STR3 = [str1 mutablecopy];    [Str3 appendstring:@ "Modify"];        NSLog (@ "str1:%p-%@ \ r \ n", str1,str1);    NSLog (@ "str2:%p-%@ \ r \ n", str2,str2);    NSLog (@ "str3:%p-%@ \ r \ n", STR3,STR3);}

Printing results:

Analysis: STR1, str2 address is the same and different from STR3 address, nsstring Copy is a shallow copy, and copy returned object is immutable object; Mutablecopy is a deep copy.

1.2 Variable Object nsmutablestring

-(void) mutablensstringtest{    nsmutablestring *mstr1 = [nsmutablestring stringwithstring:@ "test002"];        nsmutablestring *MSTR2 = [mstr1 copy];    Copy returns an immutable object, MSTR2 cannot be modified, so a crash    //[str2 appendstring:@ "test" will occur;        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);}

Printing results:

Analysis: MSTR1, MSTR2, MSTR3 address are different, Nsmutablestring object copy and mutablecopy are deep copies, and copy returns the object is immutable object.

2. Copy and Mutablecopy of collection objects

2.1 Immutable Objects Nsarray

-(void) mutablensarraytest{    nsarray *arry1 = [[Nsarray alloc] initwithobjects:@ "value1", @ "value2", nil];        Nsarray *arry2 = [arry1 copy];    Nsarray *arry3 = [Arry1 mutablecopy];        NSLog (@ "arry1:%p-%@ \ r \ n", arry1,arry1);    NSLog (@ "arry2:%p-%@ \ r \ n", Arry2,arry2);    NSLog (@ "arry3:%p-%@ \ r \ n", Arry3,arry3);}

Printing results:

2017-07-20 18:33:53.707 beck.wang[1502:194476] arry1:0x60800003b480-(    value1,    value2) 2017-07-20 18:33:53.708 beck.wang[1502:194476] arry2:0x60800003b480-(    value1,    value2) 2017-07-20 18:33:53.708 BECK.WANG[1502:194476] ARRY3:0X60800004CD20-(    value1,    

Analysis: Arry1, Arry2 address, ARR3 address is not the same, Nsarray copy is a shallow copy, and copy returned object is immutable object; Mutablecopy is a deep copy.

2.2 Variable Object Nsmutablearray

-(void) nsmutablearraytest{    nsmutablearray *marry1 = [[Nsmutablearray alloc] initwithobjects:@ "value1" @ "value2" , nil];        Nsmutablearray *marry2 = [marry1 copy];        Copy returns an immutable object, Marry2 cannot be modified, and therefore crashes    //[marry2 addobject:@ "Value3"];        Nsmutablearray *marry3 = [Marry1 mutablecopy];        NSLog (@ "marry1:%p-%@ \ r \ n", marry1,marry1);    NSLog (@ "marry2:%p-%@ \ r \ n", Marry2,marry2);    NSLog (@ "marry3:%p-%@ \ r \ n", Marry3,marry3);}

Printing results:

2017-07-20 18:55:43.243 beck.wang[1577:204641] marry1:0x600000048d60-(    value1,    value2) 2017-07-20 18:55:43.244 beck.wang[1577:204641] marry2:0x600000026000-(    value1,    value2) 2017-07-20 18:55:43.244 BECK.WANG[1577:204641] marry3:0x6000000494b0-(    value1,    

Analysis: Marry1, Marry2, MARR3 addresses are different, Nsmutablearray object copy and mutablecopy are deep copies, and copy returns objects that are immutable.

It is particularly important to note that for mutable objects of a collection class, a deep copy is not a deep copy of the strict sense, but only a single layer deep copy , that is, although the new memory address is opened, but the value stored in the memory (that is, the element in the array is still a member of the array element value, Not another copy), this is called a single-layer deep copy.

To illustrate:

-(void) singlensmutablearraytest{nsmutablearray *marry1 = [[Nsmutablearray alloc] init];    nsmutablestring *mstr1 = [[nsmutablestring alloc]initwithstring:@ "value1"];        nsmutablestring *MSTR2 = [[nsmutablestring alloc]initwithstring:@ "value2"];    [Marry1 ADDOBJECT:MSTR1];        [Marry1 ADDOBJECT:MSTR2];    Nsmutablearray *marry2 = [marry1 copy];        Nsmutablearray *marry3 = [Marry1 mutablecopy];    NSLog (@ "marry1:%p-%@ \ r \ n", marry1,marry1);    NSLog (@ "marry2:%p-%@ \ r \ n", Marry2,marry2);    NSLog (@ "marry3:%p-%@ \ r \ n", marry3,marry3);    NSLog (@ "array element address: value1:%p-value2:%p \ r \ n", marry1[0],marry1[1]);    NSLog (@ "array element address: value1:%p-value2:%p \ r \ n", marry2[0],marry2[1]);        NSLog (@ "array element address: value1:%p-value2:%p \ r \ n", marry3[0],marry3[1]);    NSLog (@ \ r \ n------------------Modify the original value------------------------\ r \ n ");        [Mstr1 appendformat:@ "AAA"];    NSLog (@ "marry1:%p-%@ \ r \ n", marry1,marry1);    NSLog (@ "marry2:%p-%@ \ r \ n", Marry2,marry2); NSLog (@ "marry3:%p-%@ \ r\ n ", marry3,marry3);    NSLog (@ "array element address: value1:%p-value2:%p \ r \ n", marry1[0],marry1[1]);    NSLog (@ "array element address: value1:%p-value2:%p \ r \ n", marry2[0],marry2[1]); NSLog (@ "array element address: value1:%p-value2:%p \ r \ n", marry3[0],marry3[1]);}

Printing results:

2017-07-20 19:48:24.539 beck.wang[1750:230132] marry1:0x60800004ae00-(value1, value2) 2017-07-20 19:48:24.539 Bec K.WANG[1750:230132] marry2:0x608000023f00-(value1, value2) 2017-07-20 19:48:24.539 beck.wang[1750:230132] Marry3: 0X60800004ABC0-(value1, value2) 2017-07-20 19:48:24.540 beck.wang[1750:230132] array element address: Value1:0x60800006df40-val UE2:0X60800006CB40 2017-07-20 19:48:24.540 beck.wang[1750:230132] array element address: value1:0x60800006df40-value2:0 X60800006CB40 2017-07-20 19:48:24.540 beck.wang[1750:230132] array element address: VALUE1:0X60800006DF40-VALUE2:0X60800006CB40 2017-07-20 19:48:24.540 beck.wang[1750:230132]------------------after modifying the original value------------------------2017-07-20 19:48:24.540 beck.wang[1750:230132] marry1:0x60800004ae00-(VALUE1AAA, value2) 2017-07-20 19:48:24.540 beck.wang[1 750:230132] marry2:0x608000023f00-(VALUE1AAA, value2) 2017-07-20 19:48:24.540 beck.wang[1750:230132] marry3:0x608 00004ABC0-(VALUE1AAA, value2) 2017-07-20 19:48:24.541 BecK.WANG[1750:230132] Array element address: VALUE1:0X60800006DF40-VALUE2:0X60800006CB40 2017-07-20 19:48:24.541 beck.wang[ 1750:230,132] Array element address: VALUE1:0X60800006DF40-VALUE2:0X60800006CB40 2017-07-20 19:48:24.541 beck.wang[1750:230132]  Array element Address: VALUE1:0X60800006DF40-VALUE2:0X60800006CB40

Analysis: Before modifying the original value, Marry1, Marry2, MARR3 address are not the same, it is clear that copy and mutablecopy are deep copies, but from the modified original value of the printing results, the deep copy here is only a deep copy of the single layer: The New memory address, However, the values in the array are still pointed to the original array, so that the values in Marry2 MARR3 are modified after the original value has been modified. In addition, from the printed array element address can be clearly seen, modified before and after Marry1, marry, MARR3 array element address are identical, more evidence of this point.

2.3 Thinking Extension: Full deep copy of the collection object

2.2 refers to the object of the collection class, deep copy is only a single layer deep copy, there is no way to achieve each layer is deep copy it? The answer is yes, we can do this at the moment:

(1) Archive solution Dafa

-(void) deplyfullcopy{    nsmutablearray *marry1 = [[Nsmutablearray alloc] init];        nsmutablestring *mstr1 = [[nsmutablestring alloc]initwithstring:@ "value1"];    nsmutablestring *MSTR2 = [[nsmutablestring alloc]initwithstring:@ "value2"];        [Marry1 ADDOBJECT:MSTR1];    [Marry1 ADDOBJECT:MSTR2];        NSData *data = [Nskeyedarchiver archiveddatawithrootobject:marry1];    Nsarray *marray2 = [Nskeyedunarchiver unarchivetoplevelobjectwithdata:data error:nil];        NSLog (@ "marry1:%p-%@ \ r \ n", marry1,marry1);    NSLog (@ "marry2:%p-%@ \ r \ n", marray2,marray2);    NSLog (@ "array element address: value1:%p-value2:%p \ r \ n", marry1[0],marry1[1]);    NSLog (@ "array element address: value1:%p-value2:%p \ r \ n", marray2[0],marray2[1]);}

Printing results:

2017-07-20 20:04:38.726 beck.wang[1833:242158] marry1:0x600000048a00-(    value1,    value2) 2017-07-20 20:04:38.726 beck.wang[1833:242158] marry2:0x600000049780-(    value1,    

Analysis: As we can see, the new memory address is opened, and the pointer address of the array element is different, which realizes the complete deep copy.

(2)-(Instancetype) Initwitharray: (nsarray<objecttype> *) array Copyitems: (BOOL) flag;

-(void) deplyfullcopy2{    nsmutablearray *marry1 = [[Nsmutablearray alloc] init];        nsmutablestring *mstr1 = [[nsmutablestring alloc]initwithstring:@ "value1"];    nsmutablestring *MSTR2 = [[nsmutablestring alloc]initwithstring:@ "value2"];        [Marry1 ADDOBJECT:MSTR1];    [Marry1 ADDOBJECT:MSTR2];        Nsarray *marray2 = [[Nsarray alloc] Initwitharray:marry1 Copyitems:yes];        NSLog (@ "marry1:%p-%@ \ r \ n", marry1,marry1);    NSLog (@ "marry2:%p-%@ \ r \ n", marray2,marray2);    NSLog (@ "array element address: value1:%p-value2:%p \ r \ n", marry1[0],marry1[1]);    NSLog (@ "array element address: value1:%p-value2:%p \ r \ n", marray2[0],marray2[1]);}

Printing results:

2017-07-20 20:08:04.201 beck.wang[1868:246161] marry1:0x610000050320-(    value1,    value2) 2017-07-20 20:08:04.202 beck.wang[1868:246161] marry2:0x6100002214c0-(    value1,    

Analysis: Ibid.

III. guidelines

No1: Both the copy and Mutablecopy methods of a Mutable object are deep copies (distinguishing between a fully deep copy and a deep copy of a single layer).

No2: The copy method of the immutable object is a shallow copy, and the Mutablecopy method is a deep copy.

The objects returned by the No3:copy method are immutable objects.

Thousand words into a picture

MORE: http://www.cnblogs.com/beckwang0912/p/7212075.html

IOS illustrated with you to understand deep and shallow copy

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.