ios设计模式--原型模式
原型模式是一种比较简单的设计模式,说简单一些,就是复制对象。
在以下情况下,会考虑使用原型模式:
1、需要创建的对象应独立于其类型与创建方式
2、要实例化的类是在运行时决定的
3、不想要与产品层次相对应的工厂层次
4、不同类的实例间的差异仅是状态的若干组合
5、类不容易创建,复制已有的组合对象对副本进行修改会更加容易
深复制与浅复制
浅复制:只复制了指针的值而不复制实际资源。浅复制在我们日常开发中使用非常普遍
1 UILabel * label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 100, 100)]; 2 label.text = @"你好"; 3 4 //label2浅复制label,两个指针同时指向同一个内存空间 5 UILabel * label2 = label; 6 7 NSLog(@"%p, %p", label, label2);
输出结果:
深复制:不仅复制了指针,还复制指针所指向的资源。
多数情况下,深复制的实现看起来并不复杂。复制必需的成员变量与资源,传给此类的新实例。
Cocoa Touch框架为NSObject的派生类提供了实现深复制的协议——NSCopying协议。
采纳了NSCoping协议的子类,需要调用- (id)copyWithZone:(NSZone *)zone这个方法,不然会发生异常。=
NSObject有一个实例方法(id)copy默认会调用[self copyWithZone:nil]。
1 //JZViewModel.h 2 3 #import <Foundation/Foundation.h> 4 5 /** 6 *Cocoa Touch框架为NSObject的派生类提供了实现深复制的协议——NSCopying协议。 7 *采纳了NSCoping协议的子类,需要调用- (id)copyWithZone:(NSZone *)zone这个方法,不然会发生异常。= 8 *NSObject有一个实例方法(id)copy默认会调用[self copyWithZone:nil]。 9 */ 10 @interface JZViewModel : NSObject <NSCopying> 11 12 @property (nonatomic, copy) NSString * name; 13 @property (nonatomic, copy) NSString * age; 14 15 - (id)initWithName:(NSString *)name andAge:(NSString *) age; 16 17 @end
1 // JZViewModel.m 2 3 #import "JZViewModel.h" 4 5 @implementation JZViewModel 6 7 //初始化方法 8 - (id)initWithName:(NSString *)name andAge:(NSString *)age 9 { 10 self = [super init]; 11 12 if(self){ 13 _name = name; 14 _age = age; 15 } 16 17 return self; 18 } 19 20 //复制 21 - (id)copyWithZone:(NSZone *)zone 22 { 23 //生成新的对象,并初始化 24 JZViewModel * viewModel = [[[self class] allocWithZone:zone] initWithName:self.name andAge:self.age]; 25 26 viewModel.name = self.name; 27 viewModel.age = self.age; 28 29 return viewModel; 30 } 31 32 - (NSString *)description 33 { 34 return [NSString stringWithFormat:@"name:%@, age:%@", self.name, self.age]; 35 } 36 37 @end
1 // ViewController.m 2 3 #import "ViewController.h" 4 #import "JZViewModel.h" 5 6 @interface ViewController () 7 8 @end 9 10 @implementation ViewController 11 12 - (void)viewDidLoad { 13 [super viewDidLoad]; 14 15 JZViewModel * viewModel = [[JZViewModel alloc] initWithName:@"小明" andAge:@"20"]; 16 NSLog(@"%@", viewModel); 17 NSLog(@"viewModel = %p", viewModel); 18 19 JZViewModel * viewModel2 = [viewModel copy]; 20 NSLog(@"%@", viewModel2); 21 NSLog(@"viewModel2 = %p", viewModel2); 22 23 } 24 25 @end
运行结果: