美文网首页面试
设计模式-原型模式

设计模式-原型模式

作者: edison0428 | 来源:发表于2018-09-27 11:43 被阅读13次

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

使用原型模式场景

  • 需要创建的对象应独立于其类型与创建方式。
  • 要实例化的类是在运行时决定的。
  • 不想要与产品层次相对应的工厂层次。
  • 不同类的实例间的差异仅是状态的若干组合。因此复制相应数量的原型比手工实例化更加方便。
  • 类不容易创建,比如每个组件可以把其他组件作为子节点的组合对象。复制已有的组合对象并对副本进行修改会更加容易。

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

  • 有很多的相关的类,其行为略有不同,而且主要差异在于内部属性,如名称等;
  • 需要使用组合(树)对象作为其他对象的基础,比如,使用组合对象作为组件来构建另一个组合对象

相关文章

网友评论

    本文标题:设计模式-原型模式

    本文链接:https://www.haomeiwen.com/subject/rejloftx.html