zoukankan      html  css  js  c++  java
  • Objective-C设计模式——原型Prototype(对象创建)

    1.原型

    原型设计模式所谓原型设计模式,其实就是对象复制,这个特性在所有语言基本上都是存在的。

    我们知道在OC中,对象赋值其实是对对象的引用复制,其实就是相当于C语言中的指针。创建了一个新的变量,但是还是指向的同一块内存地址。

    所以一旦一个引用改变了该对象的属性,那么其他指向该对象的引用全部都会发生变化。

    有时候我们并不像要这样做,我们希望重新创建一个和赋值对象一模一样的一个对象。比如我们写游戏的时候创建了一个enemy对象并对其复杂的行走路径进行了自定义,此时我们想要在创建一个。但是再次创建时,所有创建过程都要重新再写一遍,这样非常的不方便。再比如说我们创建了一个树形结构,如果想重新一个同样的对象,代价会非常大,此时我们就需要用到原型设计模式来对对象进行复制。

    何时使用

    1.需要创建的对象应独立于其类型与创建方式。

      也就是说我们想要的对象并不能够直接通过初始化函数来创建出来,其创建过程不具有普遍性且复杂。

    2.要实例化类是在运行时决定的。

      在编写代码的时候并不知道哪种对象会被创建出来,其内部的结构如何复杂(例如:复杂程度取决于用户的操作)

    3.不想要与产品层次相对应的工厂层次

      不通过工厂方法或者抽象工厂来控制产品的创建过程,想要直接复制对象

    4.不同类的实例间的差异仅是状态的若干组合。因此复制相应数量的原型比手工实例化更加方便

    5.类不容易创建,比如每个组件可把其他组件作为子节点的组合对象。复制已有的组合对象并对副本进行修改会更加容易。

      如果内部结构复杂,不容易重现。

    以下两种常见的使用场景

    1.有很多相关的类,其行为略有不同,而且主要差异在于内部属性,如名称、图像等;

    2.需要使用组合(树形)对象作为其他东西的基础,例如,使用组合对象作为组件来构建另一个组合对象。

    浅复制与深复制

    浅复制:只复制指针而不对内部对象进行复制。

    深复制:即复制指针,又为内部对象进行单独复制重新开辟内存空间。

    OC对象复制

    OC的深复制需要实现NSCopying协议及其方法

    -(id)copyWithZone:(NSZone *)zone。

    NSObject有一个实例方法是(id)copy。

    默认copy方法调用[self copy withZone:nil]

    对于采纳了NSCopying协议的子类,需要实现这个方法,否则将引发异常。iOS中,这个方法保持新的副本对象,然后将其返回。

    多数情况下深复制并不复杂,思路就是复制必须的成员变量与资源,传给此类的新实例,然后返回这个新类型。

    demo

    Prototype是实现NSCopying协议,并且实现了(id)copyWithZone:(NSZone *)zone方法的类。
     1     
     2         Prototype *type1 = [Prototype new];
     3         type1.name = @"123";
     4         Prototype *type2 = type1;
     5         if(type1.name == type2.name)
     6             NSLog(@"%p",&type1);
     7         Prototype *type3 = [type1 copy];
     8         if(type1.name == type3.name)
     9              NSLog(@"%p",&type3);
    10         type1.name =@"456";
    11         NSLog(@"%@ %@",type2.name , type3.name);
    12         
    13 /*
    14     2015-07-19 21:15:13.618 Prototype[31679:8185916] 0x7fff5fbff7e8
    15     2015-07-19 21:15:13.619 Prototype[31679:8185916] 0x7fff5fbff7d8
    16     2015-07-19 21:15:13.619 Prototype[31679:8185916] 456 123
    17 */

    可以看出来,type1属性变化时,浅复制的type2也跟着变,但是type3还是保留原值证明其为深复制。

  • 相关阅读:
    四则运算测试脚本运行情况
    AAA
    (2015秋) 软工作业成绩公布(12月26号更新)
    判断闰年的Java算法
    B
    A
    Where Amazing Happens
    安利一发资料站
    C
    B
  • 原文地址:https://www.cnblogs.com/madpanda/p/4659830.html
Copyright © 2011-2022 走看看