NSCopying协议:
1 2 3 4 5 6 7 8 9 10 11 @protocol NSCopying - (id )copyWithZone:(nullable NSZone *)zone; @end @protocol NSMutableCopying - (id )mutableCopyWithZone:(nullable NSZone *)zone; @end
分为不可变和可变两种拷贝。zone参数是被忽略的,因此可以不管。
实现:
具体怎么实现直接参考知名开源框架的写法,跟着大佬来肯定没错。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 @property (nonatomic , strong , nullable ) NSSet <NSData *> *pinnedCertificates;- (instancetype )copyWithZone:(NSZone *)zone { AFSecurityPolicy *securityPolicy = [[[self class ] allocWithZone:zone] init]; securityPolicy.SSLPinningMode = self .SSLPinningMode; securityPolicy.allowInvalidCertificates = self .allowInvalidCertificates; securityPolicy.validatesDomainName = self .validatesDomainName; securityPolicy.pinnedCertificates = [self .pinnedCertificates copyWithZone:zone]; return securityPolicy; } @property (readwrite , nonatomic , strong ) NSMutableDictionary *mutableHTTPRequestHeaders;- (instancetype )copyWithZone:(NSZone *)zone { AFHTTPRequestSerializer *serializer = [[[self class ] allocWithZone:zone] init]; dispatch_sync (self .requestHeaderModificationQueue, ^{ serializer.mutableHTTPRequestHeaders = [self .mutableHTTPRequestHeaders mutableCopyWithZone:zone]; }); serializer.queryStringSerializationStyle = self .queryStringSerializationStyle; serializer.queryStringSerialization = self .queryStringSerialization; return serializer; } #pragma mark - NSCopying - (instancetype )copyWithZone:(NSZone *)zone { AFHTTPResponseSerializer *serializer = [[[self class ] allocWithZone:zone] init]; serializer.acceptableStatusCodes = [self .acceptableStatusCodes copyWithZone:zone]; serializer.acceptableContentTypes = [self .acceptableContentTypes copyWithZone:zone]; return serializer; } @property (readwrite , nonatomic , copy ) NSArray *responseSerializers;- (instancetype )copyWithZone:(NSZone *)zone { AFCompoundResponseSerializer *serializer = [super copyWithZone:zone]; serializer.responseSerializers = self .responseSerializers; return serializer; }
如果父类实现了则必须调用super,否则会丢失信息:
1 2 3 4 5 6 7 - (instancetype )copyWithZone:(NSZone *)zone { AFPropertyListResponseSerializer *serializer = [super copyWithZone:zone]; serializer.format = self .format; serializer.readOptions = self .readOptions; return serializer; }
注意:NSObject是没有实现copy协议的。
NSObject下有两个实例方法:
1 2 - (id )copy ; - (id )mutableCopy;
他们仅仅是返回对应的copy协议方法的值。如果对象没实现则会崩溃。这两个方法只是方便使用。
1 2 This is a convenience method for classes that adopt the NSCopying protocol . An exception is raised if there is no implementation for copyWithZone :. NSObject does not itself support the NSCopying protocol. Subclasses must support the protocol and implement the copyWithZone: method . A subclass version of the copyWithZone: method should send the message to super first , to incorporate its implementation , unless the subclass descends directly from NSObject .