0%

iOS知识点(3) - NSCopying/NSMutableCopying

有时候我们需要对某些对象作快照,需要复制对象当前的状态。OC中提供了copy/mutableCopy的方法。系统提供的集合类,比人NSArray、NSSet、NSDictionary都提供了对于的方法。 对于我们自定义的对象,则可以通过实现NSCopying/NSMutableCopying协议来实现对应的功能。

NSCopying

用于对象实现自身复制的协议。复制得到一个独立的对象,所有的属性值与该对象一样。

NSCopying协议声明了一个方法 copyWithZone:。 但是所有继承NSObject的类都通过调用copy方法,间接调用copyWithZone: 实现复制。

你可以这样实现方法:

  1. 方法中通过alloc和init返回一个新的对象, 不继承copyWithZone:
  2. 通过调用父类的copyWithZone:, 然后再设置额外的属性
  3. 如果类是不可变的, 直接返回自身也可以。

如果子类也实现了NSCopying协议, 父类也有实现NSCopying, 那么子类必须重新copyWithZone:方法,调用父类的copyWithZone后,再处理自身的属性赋值。

NSMutableCopying

NSMutableCopying协议提供一个可变副本的拷贝。只有当类存在可变与不可变区别的时候才需要实现NSMutableCopying协议,否则,只需要实现NSCopying协议就可以了。 通过mutableCopy方法创建的对象,属性是可变的。

其实,具体实现还是有开发者决定。 看你在copyWithZone:/mutableCopyWithZone:中返回的是什么对象。 当然,最好还是按照苹果的规则来实现。

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
@interface CopyObjectBaseManager : NSObject <NSCopying>
{
@protected

BOOL _finishParse;
}

@property (nonatomic, strong) NSMutableDictionary<NSString *, __kindof BaseCopyObject *> *allConfig;

@end


@implementation CopyObjectBaseManager

- (id)init {
self = [super init];
if (self) {

}

return self;
}

- (NSMutableDictionary *)allConfig {
if (!_allConfig) {
_allConfig = [NSMutableDictionary dictionary];
}

return _allConfig;
}

- (id)copyWithZone:(NSZone *)zone {
CopyObjectBaseManager *manager = [[self class] allocWithZone:zone];
manager->_finishParse = _finishParse;
manager.allConfig = [self.allConfig mutableCopy]; // allConfig 是可变的

return manager;
}


@end

具体实现代码 请参考github库 https://github.com/fishmwei/iOSLearnList

欢迎关注个人公众号 微信 -> 搜索 -> fishmwei,沟通交流。