面试

设计模式-原型模式

2018-09-27  本文已影响13人  edison0428

NSCopying

NSCopying是一个与对象拷贝有关的协议。如果想让一个类的对象支持拷贝,就需要让该类实现NSCopying协议,如果不实现这个协议,直接copy的话

Person * person = [[Person alloc] init];
Person * copyPerson = person.copy;
image.png

当我们的类实现了NSCopying协议,通过类的对象调用copy方法时,copy方法就会去调用我们实现的- (id)copyWithZone:(NSZone *)zone方法,实现拷贝功能

说明:在- (id)copyWithZone:(NSZone *)zone方法中,一定要通过[self class]方法返回的对象调用allocWithZone:方法。因为指针可能实际指向的是Person的子类。这种情况下,通过调用[self class],就可以返回正确的类的类型对象

-(id)copyWithZone:(NSZone *)zone{
    
    Person * p = [[[self class] allocWithZone:zone] init];
    
    p.name = self.name;
    p.city = self.city;
    //未公开的成员
    p->provice = provice;
    return p;
    
}

调用

//创建一个实例
    Person * person = [[Person alloc] init];
    person.name = @"edison";
    NSLog(@"Person =%@ name=%@",person,person.name);
    //通过person深复制出一个新的对象prototypeCopy
    Person * copyPerson = person.copy;
    NSLog(@"copyPerson =%@  name=%@",copyPerson,copyPerson.name);
    // 通过person直接赋值,其实就是复制了指针,属于浅复制,引用计数不变
    Person * shallowCopyPerson = person;
    NSLog(@"shallowCopyPerson =%@  name=%@",shallowCopyPerson,shallowCopyPerson.name);

打印结果如下

2018-09-26 15:29:30.986120+0800 设计模式-原型模式[1102:192429] Person =<Person: 0x600000221180> name=edison
2018-09-26 15:29:30.986288+0800 设计模式-原型模式[1102:192429] copyPerson =<Person: 0x60000022d280>  name=edison
2018-09-26 15:29:30.986408+0800 设计模式-原型模式[1102:192429] shallowCopyPerson =<Person: 0x600000221180>  name=edison

NSMutableCopying

NSCopying协议与NSMutableCopying的区别主要是在于,返回的对象是否是可变类型的。以Foundation框架的NSArray为例

NSArray对象调用copy方法时,copy方法会调用- (id)copyWithZone:(NSZone *)zone,得到对象的一份拷贝,但得到的对象还是不可变的对象。而NSArray对象调用mutableCopy方法时,mutableCopy方法会调用- (id)mutableCopyWithZone:(NSZone *)zone,得到可变的对象。

如果类想要支持mutableCopy操作,则必须实现NSMutableCopying协议,也就是说实现mutableCopyWithZone方法

- (id)copyWithZone:(NSZone *)zone返回的是不可变对象,在- (id)mutableCopyWithZone:(NSZone *)zone返回的是可变对象

- (id)mutableCopyWithZone:(nullable NSZone *)zone{
    
    Person * p = [[[self class] allocWithZone:zone] init];
    
    p.name = self.name;
    p.city = self.city;
    //arr是可变数组
    p.arr  = [self.arr mutableCopyWithZone:zone];
    //未公开的成员
    p->provice = provice;
    return p;
}

原型模式的概念

image.png

使用原型模式场景

以下两种特别常见的情形,我们会想到用原型模式:

上一篇 下一篇

猜你喜欢

热点阅读