Deep copy and shallow copy learning records in iOS

Source: Internet
Author: User

 

Differences between copy and retain:

Copy is to create a new object, retain is to create a pointer, reference object count plus 1. The Copy attribute indicates that the content of the two objects is the same. The new object retain is 1, which is irrelevant to the reference count of the old object. The old object does not change. Copy reduces the context dependency of objects. The retain attribute indicates that the address of the two objects is the same (create a pointer and copy the pointer), and the content is of course the same. The retain value of this object is + 1, that is, retain is the pointer copy, and copy is the content copy.


In ios, not all objects support copy and mutableCopy. classes that comply with the NSCopying protocol can send copy messages. classes that comply with the NSMutableCopying protocol can send mutableCopy messages. If a copy or mutableCopy message is sent without complying with the appeal protocol, an exception occurs. However, the default ios class does not comply with these two protocols. To customize copy, you must comply with NSCopying and implement copyWithZone: method. to customize mutableCopy, you must comply with NSMutableCopying and implement mutableCopyWithZone: method.

 

1. Non-container objects of the system (NSString, NSNumber, etc)

 

 

NSString * string = @ Deep copy and light copy; NSString * stringCopy = [string copy]; NSMutableString * stringMCopy = [string mutableCopy]; NSLog (@ % p, string ); NSLog (@ % p, stringCopy); NSLog (@ % p, stringMCopy );

The result is as follows:

 

 

If you print retainCount at this time, you will find that the count is

 

This is why, because in fact NSString has already been autorelisted, that is, retainCount is not reliable for the objects generated by the autorelease message. Therefore, counting is meaningless.

 

 

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:@!!];        NSLog(@%p,string);    NSLog(@%p,mStringCopy);    NSLog(@%p,stringCopy);    NSLog(@%p,stringMCopy);


 

 

Conclusion: The Memory allocated by the above four NSString objects is different. However, mStringCopy is actually an immutable object. Therefore, an error is returned. For non-container objects in the system, we can think that for an immutable object, copy is Pointer copy (Shortest copy) and mutableCopy is object copy (deep copy ). If you copy a mutable object, it is a deep copy, but the object returned by copy is immutable.

 

2. system container objects

 

// Copy returns an 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 array (pointing to the same object ), the elements in the array also point to the same NSLog (@ array1 retain count: % d, [array1 retainCount]); NSLog (@ array1 retain count: % d, [arrayCopy1 retainCount]); NSLog (@ array1 address: % p, array1); NSLog (@ arrayCopy1 address: % p, arrayCopy1); NSMutableArray * mArrayCopy1 = [Array1 mutableCopy]; // mArrayCopy1 is a mutable copy of array1. It points to an object different from array1, but the element and the element in array1 point to the same object. MArrayCopy1 can also modify its own object [mArrayCopy1 addObject: @ de]; [mArrayCopy1 removeObjectAtIndex: 0]; NSLog (@ mArrayCopy1 address: % p, mArrayCopy1 ); NSLog (@ array1 =%@, array1); NSLog (@ arrayCopy1 =%@, arrayCopy1); NSLog (@ mArrayCopy1 =%@, mArrayCopy1 );


 

 

Array1 and arrayCopy1 are pointer replication, while mArrayCopy1 is object replication. mArrayCopy1 can also change the elements in the period: delete or add. But note that all elements in the container are pointer copies.

 

For containers, the element object is always pointer replication. If you want to copy element objects as objects, You need to perform deep copy.

 

 

NSArray *array = [NSArray arrayWithObjects:[NSMutableString stringWithString:@first],@b,@c,nil];        NSArray *deepCopyArray=[[NSArray alloc] initWithArray: array copyItems: YES];        NSArray* trueDeepCopyArray = [NSKeyedUnarchiver unarchiveObjectWithData:                                  [NSKeyedArchiver archivedDataWithRootObject: array]];

TrueDeepCopyArray is a full-meaning deep copy, while deepCopyArray is not. For immutable elements in deepCopyArray, it is still a pointer copy. Or we can implement the deep COPY method by ourselves. If a certain element of the container is unchangeable, the object cannot be changed after you copy it. Therefore, you only need to copy the pointer. Pointer replication is sufficient unless you assign a value to the elements in the container.

 

 

3. Custom object

If the object is defined by us, we need to implement NSCopying and NSMutableCopying so that we can call copy and mutablecopy.

 

@interface MyObj : NSObject
 
  {         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]init];                   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->imutableStr = [imutableStr copy];//       copy->name = [name copyWithZone:zone];;//       copy->imutableStr = [name copyWithZone:zone];//         copy->age = age;         return copy;}- (id)mutableCopyWithZone:(NSZone *)zone{         MyObj *copy = NSCopyObject(self, 0, zone);         copy->name = [self.name mutableCopy];         copy->age = age;         return copy;}
 

Non-pointer instance variables are not divided into shallow replication and deep replication, such as Boolean, integer, and floating point. Shortest replication and deep replication are for pointer-type instance variables. Shortest replication only copies the pointer to the copy, and the original object shares the memory data with the copy; deep Replication refers to the replication of memory resources. The original object and the copy correspond to their own memory data respectively.

 

 

Write another example.

 

Optional * srcDic = [NSMutableDictionary Syntax: @ value, @ key, nil]; NSMutableDictionary * dicCopy = [srcDic copy]; // copy NSMutableDictionary NSLog (@ srcDic: % p, % @, srcDic, srcDic); NSLog (@ dicCopy: % p % @, dicCopy, dicCopy); [dicCopy setObject: @ newValue forKey: @ key]; // try to modify the value in dicCopy

Result:
srcDic:0x7144ea0, {      key = value;  }  dicCopy:0x71445c0 {      key = value;  }  [__NSDictionaryI setObject:forKey:]: unrecognized selector sent to instance 0x71445c0  

 

Conclusion:

 

 

DicCopy obtained from [srcDic mutableCopy] has different memory addresses, that is, copy has performed deep replication on the NSMutableDictionary type. When you try to modify the value in dicCopy, an error is reported, cannot be modified. It can be determined that the copy dicCopy is an immutable copy. That is to say, copy can be a Mutable type, but it returns an immutable type.


 

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.