Objective-C Analysis of Copy syntax

Source: Internet
Author: User

In the OC syntax, the Copy syntax (Copy + MutableCopy) is provided for copying objects. Among them, it is easy to confuse the shortest copy and the deep copy.

The so-calledA shortest copy is an address copy.Does not generate a new object, but adds 1 to the reference count of the original object. WhileDeep copy: Object copyTo generate a new object copy. The counter is 1.

The following is an example of a Copy that is relatively messy:

1. For NSString/NSMutableString; NSArray/NSMutableArray... the class object provided by OC:

Take NSString/NSMutableString as an example:

For copy, the returned data must be of an unchangeable type. For mutableCopy, the returned data must be of a mutable type.

① For mutableCopy, it must be a deep copy.

// For mutableCopy, all are deep copies: the object is copied to generate a new object void strMutableCopy () {NSString * str = [[NSString alloc] initWithFormat: @ "abcd"]; // NSMutableString * str = [[NSMutableString alloc] initWithFormat: @ "abcd"]; // generate a new counter whose object counter is 1. the counter of the source object remains unchanged. NSMutableString * str2 = [str mutableCopy]; // NSString * str2 = [str mutableCopy]; // output the addresses of the two. The addresses of the two are different NSLog (@ "str --> % p", str); NSLog (@ "str2 --> % p ", str2 );}

② For copy:

If it is NSString ---> NSString; then yesShortest copy; If it is NSMutableString ---> NSString; then yesDeep copy.

If it is NSString, NSMutableString ---> NSMutableString; then it isDeep copy.

Note: there is only one case where a shortest copy occurs: immutable objects are copied to immutable objects.

// Shallow copy: the pointer copy does not produce new objects. The source object counter is added with 1 void strCopy () {NSString * str = [[NSString alloc] initWithFormat: @ "abcd"]; // because the NSString object itself is immutable, instead of generating a new object, it returns the object itself and performs a retain operation, therefore, the source object will also retain NSString * str2 = [str copy]; // output the addresses of the two. The addresses of the two are the same NSLog (@ "str --> % p ", str); NSLog (@ "str2 --> % p", str2 );}

In addition to the above cases, all others are deep copies.

For example:

// Deep copy void mutableStrCopy () {NSMutableString * str = [[NSMutableString alloc] initWithFormat: @ "abcd"]; // a new object COUNTER 1 NSString * str2 = [str copy] is generated; // the address of both is output, the two addresses are different NSLog (@ "str --> % p", str); NSLog (@ "str2 --> % p", str2 );}

Ii. Copy of custom objects: This class must implement the NSCopying protocol and rewrite the copyWithZone method.

Similarly, for mutableCopy of a custom object, the NSMutableCopying protocol must be implemented to override the mutableCopyWithZone method.

In the NSCopying protocol, there is actually only one protocol method:

@protocol NSCopying- (id)copyWithZone:(NSZone *)zone;@end


In the NSMutableCopying protocol:

@protocol NSMutableCopying- (id)mutableCopyWithZone:(NSZone *)zone;@end

The following is an example:

#import 
 
  @interface Person : NSObject
  
   @property(nonatomic,assign)int age;@property(nonatomic,copy)NSString *name;-(instancetype)initWithAge:(int)age withName:(NSString*)name;@end
  
 

#import "Person.h"@implementation Person-(instancetype)initWithAge:(int)age withName:(NSString*)name{    self = [super init];    if (self) {        self.age = age;        self.name = name;    }    return self;}-(id)copyWithZone:(NSZone *)zone{    Person* person = [[[self class] allocWithZone:zone] initWithAge:self.age withName:self.name];    return person;}@end

Int main (int argc, const char * argv []) {@ autoreleasepool {Person * p1 = [[Person alloc] initWithAge: 20 withName: @ "Jack"]; person * p2 = [p1 copy]; // outputs the addresses of two Person objects, which are different NSLog (@ "p1 --> % p", p1 ); NSLog (@ "p2 --> % p", p2);} return 0 ;}

Adding a custom object is immutable. How can this problem be solved?
-(id)copyWithZone:(NSZone *)zone{    return self;}
In this way, the addresses of the two output objects are the same.


The following describes how to create a custom class.InheritanceThe Person class.

If a subclass inherits the base class that implements the NSCopying protocol, the subclass automatically inherits the protocol. But you need to implement it again.

For example, a Student subclass inherits the Person class:

#import 
 
  #import "Person.h"@interface Student : Person@property(nonatomic,copy)NSString *school;-(instancetype)initWithAge:(int)age withName:(NSString *)name WithSchool:(NSString*)school;@end
 


#import "Student.h"@implementation Student-(instancetype)initWithAge:(int)age withName:(NSString *)name WithSchool:(NSString*)school{    self = [super initWithAge:age withName:name];    if (self) {        self.school = school;    }    return self;}-(id)copyWithZone:(NSZone *)zone{    Student *student = [super copyWithZone:zone];    student.school = self.school;    return student;}@end

Note the implementation of the copyWithZone method.



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.