What does copy mean?
1) For non-container objects such as NSString and NSNumber
NSString * str1 = @ "abc ";
NSString * str2 = [str1 copy]; // The address is the same as that of Str1.
NSString * str3 = [str1 mutableCopy]; // The address is different from str1. Although it is a deep copy, the content of str3 cannot be modified (the syntax is not passed)
NSMutableString * str4 = [str1 copy]; // The address is the same as that of Str. Modifying Str4 will crash.
NSMutableString * str5 = [str1 mutableCopy]; // The address is different from the str1 address.
NSLog (@ "str1 =====% p", str1 );
NSLog (@ "str2 ==== % p", str2 );
NSLog (@ "str3 ==== % p", str3 );
NSLog (@ "str4 ==== % p", str4 );
NSLog (@ "str5 =====% p", str5 );
[Str3 appendString: @ "xxx"]; // error, syntax error
[Str4 appendString: @ "xxx"]; // will cause the program to crash. reason: 'attempt to mutate immutable object with appendString :'
Execution result:
22:08:58. 958 test [8507: 69904] str1 ==== 0x105b407d0
22:08:58. 959 test [8507: 69904] str2 ==== 0x105b407d0
22:08:58. 959 test [8507: 69904] str3 ==== 0x7fdfc042b150
22:08:58. 959 test [8507: 69904] str4 ==== 0x105b407d0
22:08:58. 959 test [8507: 69904] str5 ==== 0x7fdfc042ca60
// ================================================ ========
NSMutableString * str1 = [NSMutableString stringWithFormat: @ "abc"]; NSString * str2 = [str1 copy]; // different NSString * str3 = [Str1 mutableCopy] for the address and str1; // The address is different from str1. Although it is a deep copy, str3 content cannot be modified (the syntax does not pass) NSMutableString * str4 = [str1 copy]; // The address is different from Str1, str4 is essentially NSString rather than NSMutableString. Modifying Str4 will crash NSMutableString * str5 = [str1 mutableCopy]; // different NSLog addresses and str1 (@ "str1 ===== % p ", str1); NSLog (@ "str2 = % p", str2); NSLog (@ "str3 = % p", str3 ); NSLog (@ "str4 = % p", str4); NSLog (@ "str5 = % p", str5 );
Execution result:
22:55:32. 116 test [11538: 104525] str1 ==== 0x7fab3949b140
22:55:32. 117 test [11538: 104525] str2 ==== 0x7fab3949e5d0
22:55:32. 117 test [11538: 104525] str3 ==== 0x7fab39490970
22:55:32. 117 test [11538: 104525] str4 ==== 0x7fab394975a0
22:55:32. 117 test [11538: 104525] str5 ==== 0x7fab3949e470
Conclusion: The copy/mutableCopy operation is a deep copy, but the actual type of the object returned by the copy operation is immutable. Modifying the copy operation will cause the program to crash; for non-mutable copy, the copy type is shortest, And the mutableCopy type is deep copy.
2) For container objects such as NSArray and NSDictionary
NSArray * array1 = [NSArray arrayWithObjects: [NSMutableString stringWithFormat: @ "a"], @ "B", @ "c", nil];
NSArray * array2 = [array1 copy]; // The address is the same as that of array1.
NSArray * array3 = [array1 mutableCopy]; // The address is different from that of array1.
NSMutableArray * array4 = [array1 copy]; // The address is the same as that of array1.
NSMutableArray * array5 = [array1 mutableCopy]; // The address is different from that of array1.
NSArray * array6 = [[NSArray alloc] initWithArray: array1 copyItems: YES]; // different from array1, the variable elements in the container are deeply copied, the immutable element is still a shortest copy.
NSArray * array7 = [NSKeyedUnarchiver unarchiveObjectWithData: [NSKeyedArchiver archivedDataWithRootObject: array1]; // different from array1, elements in the container are copied in depth.
NSMutableString * str = array5 [0];
[Str appendString: @ "xxx"];
NSMutableString * str2 = array5 [1];
// [Str2 appendString: @ "xxx"]; // causes the program to crash.
NSLog (@ "array1 ===% p", array1 );
NSLog (@ "array2 ===% p", array2 );
NSLog (@ "array3 ===% p", array3 );
NSLog (@ "array4 ===% p", array4 );
NSLog (@ "array5 ===% p", array5 );
NSLog (@ "array6 ===% p", array6 );
NSLog (@ "array7 ===% p", array7 );
NSLog (@ "array1 [0] ===% p", array1 [0]);
NSLog (@ "array2 [0] ===% p", array2 [0]);
NSLog (@ "array3 [0] ===% p", array3 [0]);
NSLog (@ "array4 [0] ===% p", array4 [0]);
NSLog (@ "array5 [0] ===% p", array5 [0]);
NSLog (@ "array6 [0] ===% p", array6 [0]);
NSLog (@ "array7 [0] ===% p", array7 [0]);
NSLog (@ "array1 [1] ===% p", array1 [1]);
NSLog (@ "array2 [1] ===% p", array2 [1]);
NSLog (@ "array3 [1] ===% p", array3 [1]);
NSLog (@ "array4 [1] ===% p", array4 [1]);
NSLog (@ "array5 [1] ===% p", array5 [1]);
NSLog (@ "array6 [1] ===% p", array6 [1]);
NSLog (@ "array7 [1] ===% p", array7 [1]);
NSLog (@ "array1 [0] ===%@", array1 [0]);
NSLog (@ "array2 [0] ===%@", array2 [0]);
NSLog (@ "array3 [0] ===%@", array3 [0]);
NSLog (@ "array4 [0] ===%@", array4 [0]);
NSLog (@ "array5 [0] ===%@", array5 [0]);
NSLog (@ "array6 [0] ===%@", array6 [0]);
NSLog (@ "array7 [0] ===%@", array7 [0]);
Execution result:
23:15:46. 235 test [12791: 118074] array1 === 0x7fc6e1d1dab0
23:15:46. 236 test [12791: 118074] array2 === 0x7fc6e1d1dab0
23:15:46. 236 test [12791: 118074] array3 === 0x7fc6e1d2ef40
23:15:46. 236 test [12791: 118074] array4 === 0x7fc6e1d1dab0
23:15:46. 236 test [12791: 118074] array5 === 0x7fc6e1d19430
23:15:46. 236 test [12791: 118074] array6 === 0x7fc6e1d2fc60
23:15:46. 236 test [12791: 118074] array7 === 0x7fc6e1c30cd0
23:15:46. 237 test [12791: 118074] array1 [0] === 0x7fc6e1d1ba10
23:15:46. 237 test [12791: 118074] array2 [0] === 0x7fc6e1d1ba10
23:15:46. 237 test [12791: 118074] array3 [0] === 0x7fc6e1d1ba10
23:15:46. 237 test [12791: 118074] array4 [0] === 0x7fc6e1d1ba10
23:15:46. 237 test [12791: 118074] array5 [0] === 0x7fc6e1d1ba10
23:15:46. 237 test [12791: 118074] array6 [0] === 0x7fc6e1d2fc40
23:15:46. 238 test [12791: 118074] array7 [0] === 0x7fc6e1c2faf0
23:15:46. 238 test [12791: 118074] array1 [1] === 0x10fd197f0
23:15:46. 238 test [12791: 118074] array2 [1] === 0x10fd197f0
23:15:46. 238 test [12791: 118074] array3 [1] === 0x10fd197f0
23:15:46. 238 test [12791: 118074] array4 [1] === 0x10fd197f0
23:15:46. 239 test [12791: 118074] array5 [1] === 0x10fd197f0
23:15:46. 239 test [12791: 118074] array6 [1] === 0x10fd197f0
23:15:46. 239 test [12791: 118074] array7 [1] === 0x7fc6e1c2fc50
23:15:46. 239 test [12791: 118074] array1 [0] === axxx
23:15:46. 239 test [12791: 118074] array2 [0] === axxx
23:15:46. 239 test [12791: 118074] array3 [0] === axxx
23:15:46. 240 test [12791: 118074] array4 [0] === axxx
23:15:46. 240 test [12791: 118074] array5 [0] === axxx
23:15:46. 240 test [12791: 118074] array6 [0] ===
23:15:46. 240 test [12791: 118074] array7 [0] ===
Conclusion: the conclusions of non-container objects are also applicable to the container objects, but the elements in the container objects are always shortest copies. if you want to make a deep copy of the elements in the container in a true sense, you can archive them.
Official link: https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/Collections/Articles/Copying.html