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.