原型模式的定义

原型模式(Prototype)即应用于“复制”操作的模式,此模式最初定义在《设计模式》(Addison-Wesley,1994),里面是这样定义的“使用原型实例指定创建对象的种类,并通过复制这个原型创建新的对象”。简单理解就是根据这个原型创建新的对象,这种创建是指深复制,得到一份新的内存资源,而不是一个新的指针引用。

浅复制与深复制

非指针型实例变量没有浅复制与深复制之分,像布尔型、整型、浮点型。浅复制与深复制是针对指针型实例变量说的,浅复制就只是复制了指针到副本中,原始对象与副本共享同一内存数据;深复制就是把内存的资源也复制了,原始对象和副本各自拥有自己的内存数据。下面的示意图左边为浅复制,右边为深复制。Cocoa Touch框架为NSObject的派生类提供了复制协议即NSCopying协议,NSObject子类需要实现其方法(id)copyWithZone:(NSZone *)zone。NSObject有一个实例方法(id)copy,这个方法默认调用了[self copyWithZone:nil],当然在里面你可以实现浅复制,也可以实现深复制。

   

 

原型模式即是对原有对象的复制,当我们对一个对象进行copy的时候,必须先让其类遵循<NSCopying>协议,然后在类的.m文件中实现以下方法即可:

- (id)copyWithZone:(NSZone *)zone

{

    return [类名 allocWithZone:zone];

}

例子: 

新建person类,person.h文件如下:

@interface person : NSObject<NSCopying>

@property (nonatomic, copy) NSString* name;

@end

实现深复制,person.m文件如下:

#import "person.h"

 @implementation person

- (id)copyWithZone:(NSZone *)zone

{

    return [person allocWithZone:zone];

}

@end

 

测试代码:

   //创建一个对象

    person* p = [[person alloc] init];

        p.name = @"haha";

        NSLog(@"%@--%@--%@", p.name, p, [p class]);

   //复制一个对象

        person* p1 = [p copy];

        NSLog(@"%@--%@--%@--%@", p1.name, p, [p1 class], p1);

   //复制一个对象

        person* p2 = p;

        p2.name = @"520";

        NSLog(@"%@--%@--%@--%@", p2.name, p, [p2 class], p2);

        NSLog(@"%@", p.name);

测试结果:

haha--<person: 0x100114680>--person

(null)--<person: 0x100114680>--person--<person: 0x100114ba0>

520--<person: 0x100114680>--person--<person: 0x100114680>

520

 结论:

1、 我们在copyWithZone:(NSZone *)zone实现了深复制,p通过copy复制得到新对象p1,从输出结果来看,内存地址与p是不一样的,另外复制得到p1后修改了p1的name,对p的name值没有影响,可判断为深复制;

2、使用直接赋值得到的p2,内存地址与p一样,只是简单的指针复制,另外从修改了p2的name值同时也影响了p的name值也可以看出,这种为浅复制。

另外:

像 NSString、NSDictionary这些类,本身已经实现了copyWithZone:(NSZone *)zone方法,直接使用如[NSString copy]调用即可。在复制后得到的副本,又可以分为可变副本(mutable copy)和不可变副本(immutable copy)。通常在NSCopying协议规定的方法copyWithZone中返回不可变副本,在NSMutableCopying的mutableCopyWithZone方法中返回可变副本,然后调用copy和mutableCopy方法来得到副本。

代码如下:

测试结果:

代码如下:

测试结果:

 

posted on 2016-05-24 15:47  支烟慢点点  阅读(179)  评论(0编辑  收藏  举报