Objective-c talk about the deep copy, copy and mutable copy are not completely copied
Source: Internet
Author: User
(1) Pointer assignment in string, copy and mutablecopy
NSString and NSString
(1) Pointer assignment
Must point to the same string address.
(2) copy (same as direct pointing)
NSString * [email protected] "aaa";
NSString * str2 = [str1 copy];
NSLog (@ "str1:% p ---- str2:% p", & str1, & str2); // Pointer address output, not the same, indicating that the pointer is newly created
NSLog (@ "str1:% p ---- str2:% p", str1, str2); // Pointer points to the content address output, it is the same, indicating that the content has not been copied
The results show that Copy did not implement copying, indicating that the following cases are equivalent and all point to the same memory area
NSString * str2 = str1;
NSString * str3 = [[NSString alloc] initWithString: str1];
NSString * str4 = [NSString stringWithString: str1];
NSString * str5 = [str1 copy];
If the scene requires, for example, to destroy a place pointed to by str1, you must first copy to a new address, and then use str2 to copy the NSString.
(3) mutablecopy (implemented copy)
NSString * [email protected] "aaa";
NSString * str2 = [str1 mutableCopy];
NSLog (@ "str1:% p ---- str2:% p", & str1, & str2); // Pointer address output, not the same, indicating that the pointer is newly created
NSLog (@ "str1:% p ---- str2:% p", str1, str2); // The pointer points to the content address output, which is different, indicating that the memory is reopened, and the content of str1 is copied to the new memory , The str2 variable points to this new address
NSMutableString to NSMutableString
(1) Pointer assignment:
Must point to the same variable string address.
(2) mutablecopy
NSMutableString * mStr = [NSMutableString stringWithString: @ "abc"];
NSMutableString * mStr2 = [mStr mutableCopy];
NSLog (@ "mstr:% p ----- mstr2:% p", mStr, mStr2); // The pointer content address is different, indicating that the copy is implemented
[mStr2 appendString: @ "def"];
NSLog (@ "mstr:% @ ----- mstr2:% @", mStr, mStr2); // Not related to each other
In this way, a copy of NSMutableString is realized, and two independent variable strings are generated.
(3) copy (error, will collapse)
NSMutableString * mStr2 = [mStr copy];
NSMutableString to NSString
(1) Pointer assignment:
NSMutableString * mStr = [NSMutableString stringWithString: @ "abc"];
NSString * str = mStr;
NSLog (@ "mstr:% p ----- str:% p", mStr, str); // The pointer points to the same content address, indicating that the change of mStr will link str
[mStr appendString: @ "def"];
NSLog (@ "mstr:% @ ----- str:% @", mStr, str); // The change of mStr affected str
In this case, the change of mStr will affect str, but the change of str will be redirected, and will not affect mStr
(2) Copy and mutablecopy:
NSMutableString * mStr = [NSMutableString stringWithString: @ "abc"];
NSString * str = [mStr copy]; // NSString * str = [mStr mutableCopy]; can also be achieved
NSLog (@ "mstr:% p ----- str:% p", mStr, str);
In this case, str copies mStr, and the change of mStr does not affect str.
But in this, [mStr copy] and [mstr mutableCopy], although both copy the original mStr and open up a new memory area, the difference is that the object copied by the former is immutable, and the latter is mutable. The assignment of variable strings to NSString actually loses its dynamicity.
NSString to NSMutableString
Using copy method, let NSString assign value to NSMutableString is also a dead act, you should use StringWithString method to initialize NSMutableString
1. Between NSString, copy can not achieve copy (equivalent direct pointing), must be mutablecopy to achieve copy
2. Between NSMutableString, Mutablecopy realizes copying.
3. For NSMutableString copy to NSString, both copy and mutablecopy can complete the task.
So: For copying between strings, Mutablecopy must be used to achieve copying.
Direct assignment of array variable assignment, copy and mutablecopy
NSArray and NSArray
(1) Direct pointing
It must point to the same array.
(2) copy
NSArray * array1 = [NSArray arrayWithObjects: @ "1", @ "2", @ "3", nil];
NSArray * array2 = [array1 copy];
NSLog (@ "arr1:% p, arr2:% p", & array1, & array2); // The pointer addresses are different, indicating that they are two different pointer variables
NSLog (@ "arr1:% p, arr2:% p", array1, array2); // The array pointer points to the same content, indicating that the copy method is still directly pointed to NSArray, no copy
NSLog (@ "arr1:% p, arr2:% p", array1 [0], array2 [0]); // The array address is the same, the content address must be the same
Explain that copy does not implement copy, and still points to the same array.
(3) mutablecopy
NSArray * array1 = [NSArray arrayWithObjects: @ "1", @ "2", @ "3", nil];
NSArray * array2 = [array1 mutableCopy];
NSLog (@ "arr1:% p, arr2:% p", & array1, & array2); // Different pointer variables, different addresses
NSLog (@ "arr1:% p, arr2:% p", array1, array2); // The array address is different, indicating that the array is copied
NSLog (@ "arr1:% p, arr2:% p", array1 [0], array2 [0]); // The element address is the same, indicating that the element has not been copied
It means that the copy is realized, but the pointer of the element in the array is copied, but the element is not copied.
NSMutableArray and NSMutableArray
(1) Direct pointing
The same thing. It must be changed together.
(2) mutablecopy
NSMutableArray * mArray1 = [NSMutableArray arrayWithObjects:
[NSMutableString stringWithString: @ "1"],
[NSMutableString stringWithString: @ "2"],
[NSMutableString stringWithString: @ "3"], nil];
NSMutableArray * mArray2 = [mArray1 mutableCopy];
NSLog (@ "arr1:% p, arr2:% p", & mArray1, & mArray2); // The pointer addresses are different, indicating that they are two different pointers
NSLog (@ "arr1:% p, arr2:% p", mArray1, mArray2); // The array address is different, indicating that the array has been copied
NSLog (@ "arr1:% p, arr2:% p", mArray1 [0], mArray2 [0]); // The content address is the same, indicating that the content is not copied
Explain that mutablecopy implements copying, but does not implement copying of internal elements of the array.
In the case where this content is a variable element, if the variable array 1 element is changed, the variable array 2 element will also be changed together. There is no complete copy. To achieve a full copy, we must continue to peel apart layers, all copies and then reorganize the array.
Description:
1. Like NSString, the copy method of NSArray does not actually implement a little copy (same as direct pointing), only Mutablecopy can achieve copy.
2. But mutablecopy only copies the array itself and the pointer of each element in the array, and does not implement the copying of array elements.
Custom class implements NSCopying and NSMutableCopying protocols
If these two protocols are not implemented, neither the copy nor mutablecopy methods will get a response, and the degree of specific copying also depends on the specific implementation
-(id) copyWithZone: (NSZone *) zone
{
Student * stu = [[Student allocWithZone: zone] initWithName: self.name GradeArray: self.GradeArray];
return stu;
}
-(id) mutableCopyWithZone: (NSZone *) zone {
Student * stu = [[Student allocWithZone: zone] initWithName: self.name GradeArray: self.GradeArray];
return stu;
}
@end
copy:
Student * stu1 = [[Student alloc] init];
[email protected] "stu1";
stu1.GradeArray = [[NSMutableArray alloc] init];
[stu1.GradeArray addObject: @ "100"];
Student * stu2 = [stu1 mutableCopy];
NSLog (@ "stu1:% p ---- stu2:% p", stu1, stu2); // stu1: 0x7faa43c1b050 ---- stu2: 0x7faa43c1d0d0
NSLog (@ "stu1:% p ---- stu2:% p", stu1.name, stu2.name); // stu1: 0x10df5f080 ---- stu2: 0x10df5f080
NSLog (@ "stu1:% p ---- stu2:% p", stu1.GradeArray, stu2.GradeArray); // stu1: 0x7faa43c1ad40 ---- stu2: 0x7faa43c1ad40
It means that the object is copied, but the content pointed by the member's pointer is not copied.
For custom objects, the deepest copy can only be to the extent of copying the member pointer, indicating that neither copy nor mutablecopy is a complete copy
To sum up, if you want to achieve a complete copy of an object:
1. Mutablecopy must be performed on each object in Class separately (for basic data objects, copy is not necessarily OK)
2. And if there are objects of container nature (such as Array and MutableArray) in Class, currently only the array is copied, and the contents of the elements in the variable array are not copied. You must fully copy and dig deeper. Mutablecopy of each element
It is not a complete copy until an object that does not exist in a container is mutablecopyed
Student * stu1 = [[Student alloc] init];
[email protected] "stu1";
stu1.GradeArray = [[NSMutableArray alloc] init];
[stu1.GradeArray addObject: @ "100"];
Student * stu2 = [stu1 mutableCopy];
stu2.name = [stu1.name mutableCopy];
stu2.GradeArray = [stu1.GradeArray mutableCopy];
NSLog (@ "stu1:% p ---- stu2:% p", stu1, stu2); // stu1: 0x7faa43c1b050 ---- stu2: 0x7faa43c1d0d0
NSLog (@ "stu1:% p ---- stu2:% p", stu1.name, stu2.name); // stu1: 0x10df5f080 ---- stu2: 0x10df5f080
NSLog (@ "stu1:% p ---- stu2:% p", stu1.GradeArray, stu2.GradeArray); // stu1: 0x7faa43c1ad40 ---- stu2: 0x7faa43c1ad40
So a better way is to archive first and then unpack as stated in the last blog
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.