Brief analysis of shallow copy and deep copy (copy and mutablecopy) in IOS _ios

Source: Internet
Author: User
Tags shallow copy

iOS provides a copy and Mutablecopy method, as the name suggests, copy is a copy of a Imutable object, and Mutablecopy is a copy of a mutable object.

The difference between copy and retain:

Copy is to create a new object, retain is to create a pointer, reference object Count plus 1. The Copy property indicates that the contents of two objects are the same, the new object retain to 1, regardless of the reference count of the old object, and the old object does not change. Copy reduces the dependency of the object on the context.

The Retain property indicates that two objects have the same address (creating a pointer, a copy of the pointer), and of course the same content, the retain value of the object +1 that is, retain is a pointer copy, copy is a copy of the content.

Of course, not all objects in iOS support Copy,mutablecopy, classes that follow the Nscopying protocol can send copy messages, and classes that comply with the Nsmutablecopying protocol can send mutablecopy messages. If you send a copy or mutablecopy without complying with the appeal two agreements, an exception will occur. But the default iOS class does not follow these two protocols. If you want to customize copy then you must follow the nscopying and implement the Copywithzone: method, if you want to customize the mutablecopy then you must obey nsmutablecopying and implement Mutablecopywithzone: Method.

First, we need to have this premise:

[Array addobject:obj];

This will increase the reference count of obj by 1, and if you use remove the reference count for obj will be reduced by one.

This is what iOS does with the collection's memory processing.

So, suppose that obj is only owned by an array:

ID temp = [array objectatindex:0];
[Array removeobjectatindex:0];

If you're going to use temp again, you're going to make a mistake, because obj has been released this time.

(To be reminded, if you're testing with nsstring, note that @ "ABC" is constant:-) )

Because the values of collection classes are often encountered in a program, a simple retain is not necessarily sufficient and requires a copy of the contents of the collection, which is a deep copy.

Let's look at the following.

iOS provides a copy and Mutablecopy method, as the name suggests, copy is a copy of a Imutable object, and Mutablecopy is a copy of a mutable object.

Here are a few examples to illustrate.

1. Non-Container class object of the system

This refers to objects such as Nsstring,nsnumber and so on.

NSString *string = @ "Origion";
NSString *stringcopy = [string copy];
Nsmutablestring *stringmcopy = [string mutablecopy];
[Stringmcopy appendstring:@ "!!"];

Looking at memory, you can see that string and stringcopy point to the same area of memory (also known as Apple weak reference weak reference), where the reference count for Stringcopy is equal to 2 for string. And Stringmcopy is what we call the real copy, the system assigns new memory to it, but the string that the pointer points to is the same as string.

Look at the following example:

nsmutablestring *string = [nsmutablestring stringwithstring: @ "origion"];
NSString *stringcopy = [string copy];
Nsmutablestring *mstringcopy = [string copy];
Nsmutablestring *stringmcopy = [string mutablecopy];
[Mstringcopy appendstring:@ "MM"];//error
[string appendstring:@ "origion!"];
[Stringmcopy appendstring:@ "!!"];

The memory allocated by the above four NSString objects is not the same. But for Mstringcopy is actually a imutable object, so the above will be an error.
For the system's non container class object, we can assume that if copying to an immutable object, copy is a pointer copy (shallow copy) and Mutablecopy is an object copy (deep copy). If you copy a variable object, it is a deep copy, but the object returned by copy is immutable.

2. The system's container class object

Refer to Nsarray,nsdictionary, etc. For the container class itself, the conclusions discussed above are also applicable and need to be explored for changes in the objects within the container after replication.

Copy returns the immutable object, MUTABLECOPY returns the variable object
nsarray *array1 = [Nsarray arraywithobjects:@ "a", @ "B", @ "C", nil];
Nsarray *arraycopy1 = [array1 copy];
ArrayCopy1 is the same Nsarray object as the array (pointing to the same object), including the elements inside the array that point to the same pointer
NSLog (@ array1 retain count:%d, [array1 Retaincount]);
NSLog (@ "Array1 retain count:%d", [arrayCopy1 Retaincount]);
Nsmutablearray *marraycopy1 = [Array1 mutablecopy];
MArrayCopy1 is a mutable copy of array1 that points to different objects and array1, but the elements in them and the elements in Array1 point to the same object. MArrayCopy1 can also modify their own objects
[mArrayCopy1 addobject:@ "de"];
[MArrayCopy1 removeobjectatindex:0];

Array1 and ArrayCopy1 are pointer replications, and MArrayCopy1 is Object replication, and mArrayCopy1 can also change elements in the period: delete or Add. Note, however, that the element content within the container is a pointer copy.

Here's another example to test.

Nsarray *marray1 = [Nsarray arraywithobjects:[nsmutablestring stringwithstring:@ "A"],@ "B", @ "C", nil];
Nsarray *marraycopy2 = [mArray1 copy];
NSLog (@ "MArray1 retain count:%d", [MArray1 Retaincount]);
Nsmutablearray *marraymcopy1 = [MArray1 mutablecopy];
NSLog (@ "MArray1 retain count:%d", [MArray1 Retaincount]);
Marraycopy2,marraymcopy1 and MArray1 point to different objects, but the elements are the same object-the same pointer
//test
nsmutablestring *teststring = [MArray1 objectatindex:0];
TestString = @ "1a1";//This will change the teststring pointer, in fact, assign the @ "1a1" temporary object to teststring
[teststring appendstring:@ "tail"];// So the first element of the above three arrays has been changed

Thus, for a container, its element object is always a pointer copy. If you need an element object that is also an object copy, you need to implement a deep copy.

http://developer.apple.com/library/mac/#documentation/cocoa/conceptual/collections/articles/copying.html
Nsarray *array = [Nsarray arraywithobjects:[nsmutablestring stringwithstring:@ "The" "," "],[nsstringstringwithstring:@" B "],@" C ", nil];
Nsarray *deepcopyarray=[[nsarray alloc] Initwitharray:array Copyitems:yes];
nsarray* Truedeepcopyarray = [nskeyedunarchiver unarchiveobjectwithdata:
[Nskeyedarchiver Archiveddatawithrootobject:array]];

Truedeepcopyarray is a deep copy of the full sense, and Deepcopyarray is not, for the immutable elements within Deepcopyarray or pointer replication. Or our own way to achieve deep copy. Because if one element of a container is immutable, the object remains unchanged after you copy it, so you only need to copy the pointer. The pointer copy is sufficient unless you reassign the elements within the container.

For example, [[Array objectatindex:0]appendstring:@ "SD"] the other container objects are not affected.

[[Array objectatindex:1] and [[Deepcopyarray objectatindex:0], although pointing to the same block of memory, we have no way to modify it-because it is immutable. So the pointer copy is enough.

So this is not exactly a deep copy, but Apple's official document listed it as deep copy, and added copy and mutablity relationship instructions, so do a note here (there is a bit of doubt, understand the enlighten AH).

Or our own way to achieve deep copy (slightly).

3. Custom Objects

If it is the object we define, then we have to implement nscopying,nsmutablecopying ourselves so that we can invoke copy and Mutablecopy. As an example:

@interface myobj:nsobject<nscopying,nsmutablecopying> {nsmutablestring *name;
NSString *imutablestr;
int age;
} @property (nonatomic, retain) nsmutablestring *name;
@property (nonatomic, retain) NSString *imutablestr;
@property (nonatomic) int age;
@end @implementation myobj @synthesize name;
@synthesize age;
@synthesize Imutablestr; -(ID) init {if (self = [super init]) {self.name = [[nsmutablestring alloc]init]; self.imutablestr = [[NSString Alloc]ini
T];
Age =-1;
return self;
}-(void) Dealloc {[Name release];
[Imutablestr release];
[Super Dealloc]; 
}-(ID) Copywithzone: (Nszone *) Zone {myobj *copy = [[[Self class] allocwithzone:zone] init]; copy->name = [name copy];
COPY-&GT;IMUTABLESTR = [imutablestr copy];
Copy->name = [name Copywithzone:zone];;
COPY-&GT;IMUTABLESTR = [name copywithzone:zone];//copy->age = age;
return copy; }-(ID) Mutablecopywithzone: (Nszone *) Zone {myobj *copy = Nscopyobject (self, 0, zone); copy->name = [Self.name mutable Copy];
Copy->age = age;
return copy; }

About the shallow copy and deep copy in iOS (copy and mutablecopy) to introduce so much, I hope to help you!

Related Article

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.