0%

NSCopying协议

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]; //对象类型调用copyWithZone,需要确保对象已经实现了copy协议。这里不需要可变所以调用copyWithZone

return securityPolicy;
}


@property (readwrite, nonatomic, strong) NSMutableDictionary *mutableHTTPRequestHeaders;
- (instancetype)copyWithZone:(NSZone *)zone {
AFHTTPRequestSerializer *serializer = [[[self class] allocWithZone:zone] init];
dispatch_sync(self.requestHeaderModificationQueue, ^{
//这里需要可变所以调用mutableCopyWithZone
serializer.mutableHTTPRequestHeaders = [self.mutableHTTPRequestHeaders mutableCopyWithZone:zone];
});
serializer.queryStringSerializationStyle = self.queryStringSerializationStyle;
serializer.queryStringSerialization = self.queryStringSerialization;

return serializer;
}

//---AFHTTPResponseSerializer
#pragma mark - NSCopying

- (instancetype)copyWithZone:(NSZone *)zone {
AFHTTPResponseSerializer *serializer = [[[self class] allocWithZone:zone] init]; //不能写死为[AFHTTPResponseSerializer allocWithZone:zone]
serializer.acceptableStatusCodes = [self.acceptableStatusCodes copyWithZone:zone];
serializer.acceptableContentTypes = [self.acceptableContentTypes copyWithZone:zone];

return serializer;
}

//---AFCompoundResponseSerializer:AFHTTPResponseSerializer
@property (readwrite, nonatomic, copy) NSArray *responseSerializers;
- (instancetype)copyWithZone:(NSZone *)zone {
AFCompoundResponseSerializer *serializer = [super copyWithZone:zone];
serializer.responseSerializers = self.responseSerializers; //responseSerializers属性是copy,所以可以直接赋值。setter方法里会调用copy.

return serializer;
}

如果父类实现了则必须调用super,否则会丢失信息:

1
2
3
4
5
6
7
- (instancetype)copyWithZone:(NSZone *)zone {
AFPropertyListResponseSerializer *serializer = [super copyWithZone:zone]; //调用super
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.
觉得文章有帮助可以打赏一下哦!