原型模式的解析-iOS

栏目: IOS · 发布时间: 5年前

内容简介:原型模式的解析-iOS其他设计模式的介绍1、简单工厂模式、工厂模式、抽象工厂模式的解析-iOS

原型模式的解析-iOS

其他 设计模式 的介绍

1、简单工厂模式、工厂模式、抽象工厂模式的解析-iOS 

2、建造者模式的解析-iOS 

3、单例模式的解析-iOS 

4、原型模式的解析-iOS 

5、代理模式的解析-iOS 

6、适配器模式的解析-iOS 

7、装饰器模式的解析-iOS 

8、外观模式的解析-iOS 

9、桥接模式的解析-iOS 

10、组合模式的解析-iOS

概率描述

用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。百度百科

实用场景

“某些结构复杂的对象”的创建工作;由于需求的变化,这些对象经常面临着剧烈的变化,但是他们却拥有比较稳定一致的接口。百度百科

在Objective-C中使用原型模式 

在Objective-C中使用原型模式,就是说对对象的复制,就是我们常说的深拷贝和浅拷贝。在Cocoa Touch框架为NSObject的派生类提供了实现深拷贝的协议和相应的方法,NSCopying协议和-(id)copyWithZone:(NSZone )zone的方法。还有就是NSMutableCopying 和-(id)mutableCopyWithZone:(NSZone )zone的协议和方式。 

也就是说如果要实现拷贝,就需要实现NSCopying协议和-(id)copyWithZone:(NSZone )zone的方法。如果是可变的要实现NSMutableCopying协议和-(id)copyWithZone:(NSZone )zone方法。

深拷贝、浅拷贝

浅拷贝:只是复制了指针的地址,并没有复制该指针指向的地址。

深拷贝:不但复制了指针的地址,还复制了指针地址指向的值。

代码解析:

-(void)shallowAndDeepCopy{

    /*******集合类的**********/

    //非可变集合

    NSDictionary *prototypeDic = @{@"A":@"1",@"B":@"2",@"C":@"3",@"D":@"4"};

    NSDictionary  *copyDicOne = prototypeDic.copy;

    NSDictionary  *copyDicTwo = prototypeDic.mutableCopy;



    NSLog(@"集合类的拷贝------------\n   prototypeDic的内容地址-%p \n copyDicOne-copy-的内容地址-%p  \n copyDicTwo-Mutable-的内容地址-%p  \n",prototypeDic,copyDicOne,copyDicTwo);

    NSLog(@"集合类的拷贝------------\n   prototypeDic的指针地址-%p \n copyDicOne-copy-的指针地址-%p   \n copyDicTwo-Mutable-的指针地址-%p  \n",&prototypeDic,&copyDicOne,&copyDicTwo);



    //可变集合

    NSMutableDictionary *prototypeMutableDic =[[NSMutableDictionary alloc]initWithObjectsAndKeys:@"A",@"1",@"B",@"2",@"C",@"3",@"D",@"4", nil ];

    NSMutableDictionary  *copyMutaleDicOne = prototypeMutableDic.copy;

    NSMutableDictionary  *copyMutaleDicTwo = prototypeMutableDic.mutableCopy;



    NSLog(@"可变集合类的拷贝------------\n   prototypeMutableDic的内容地址-%p \n copyMutaleDicOne-copy-的内容地址-%p \n copyMutaleDicTwo-Mutable-的内容地址-%p  \n",prototypeMutableDic,copyMutaleDicOne,copyMutaleDicTwo);

    NSLog(@"可变集合类的拷贝------------\n   prototypeMutableDic的指针地址-%p \n copyMutaleDicOne-copy-的指针地址-%p \n copyMutaleDicTwo-Mutable-的指针地址-%p  \n",&prototypeMutableDic,&copyMutaleDicOne,&copyMutaleDicTwo);





    /**********非集合类的**********/

    //不可变的

    NSString *prototypeStr = @"猪猪侠";

    NSString *copyStrOne = prototypeStr.copy;

    NSString *copyStrTwo = prototypeStr.mutableCopy;



    NSLog(@"非集合类的拷贝------------\n   prototypeStr的内容地址-%p \n copyStrOne-copy-的内容地址-%p  \n copyStrTwo-Mutable-的内容地址-%p \n",prototypeStr,copyStrOne,copyStrTwo);

    NSLog(@"非集合类的拷贝------------\n   prototypeStr的指针地址-%p \n copyStrOne-copy-的指针地址-%p  \n copyStrTwo-Mutable-的指针地址-%p \n",&prototypeStr,&copyStrOne,&copyStrTwo);



    //可变的

    NSMutableString *prototypeMutableStr = [[NSMutableString alloc]initWithString:@"小猪佩奇"];

    NSMutableString *copyMutabelStrOne = prototypeMutableStr.copy;

    NSMutableString *copyMutabelStrTwo = prototypeMutableStr.mutableCopy;

    NSLog(@"可变非集合类的拷贝------------\n   prototypeMutableStr的内容地址-%p \n copyMutabelStrOne-copy-的内容地址-%p   \n  copyMutabelStrTwo-Mutable-的内容地址-%p \n",prototypeMutableStr,copyMutabelStrOne,copyMutabelStrTwo);

    NSLog(@"可变非集合类的拷贝------------\n   prototypeMutableStr的指针地址-%p \n copyMutabelStrOne-copy-的指针地址-%p   \n  copyMutabelStrTwo-Mutable-的指针地址-%p \n",&prototypeMutableStr,&copyMutabelStrOne,&copyMutabelStrTwo);



}

打印的结果

2018-06-12 15:04:35.457387+0800 DesignDemo[17492:692166] 集合类的拷贝------------

   prototypeDic的内容地址-0x6000000f2100 

 copyDicOne-copy-的内容地址-0x6000000f2100  

 copyDicTwo-Mutable-的内容地址-0x60000023e540  



2018-06-12 15:04:35.457509+0800 DesignDemo[17492:692166] 集合类的拷贝------------

   prototypeDic的指针地址-0x7ffeecd84988 

 copyDicOne-copy-的指针地址-0x7ffeecd84980   

 copyDicTwo-Mutable-的指针地址-0x7ffeecd84978  



2018-06-12 15:04:35.457617+0800 DesignDemo[17492:692166] 可变集合类的拷贝------------

   prototypeMutableDic的内容地址-0x60000023ce40 

 copyMutaleDicOne-copy-的内容地址-0x60000023d2c0 

 copyMutaleDicTwo-Mutable-的内容地址-0x600000420160  



2018-06-12 15:04:35.457896+0800 DesignDemo[17492:692166] 可变集合类的拷贝------------

   prototypeMutableDic的指针地址-0x7ffeecd84970 

 copyMutaleDicOne-copy-的指针地址-0x7ffeecd84968 

 copyMutaleDicTwo-Mutable-的指针地址-0x7ffeecd84960  



2018-06-12 15:04:35.458083+0800 DesignDemo[17492:692166] 非集合类的拷贝------------

   prototypeStr的内容地址-0x102e7c4d8 

 copyStrOne-copy-的内容地址-0x102e7c4d8  

 copyStrTwo-Mutable-的内容地址-0x604000442580 



2018-06-12 15:04:35.458478+0800 DesignDemo[17492:692166] 非集合类的拷贝------------

   prototypeStr的指针地址-0x7ffeecd84958 

 copyStrOne-copy-的指针地址-0x7ffeecd84950  

 copyStrTwo-Mutable-的指针地址-0x7ffeecd84948 



2018-06-12 15:04:35.458711+0800 DesignDemo[17492:692166] 可变非集合类的拷贝------------

   prototypeMutableStr的内容地址-0x600000257df0 

 copyMutabelStrOne-copy-的内容地址-0x60000023d440   

  copyMutabelStrTwo-Mutable-的内容地址-0x600000257c10 



2018-06-12 15:04:35.459056+0800 DesignDemo[17492:692166] 可变非集合类的拷贝------------

   prototypeMutableStr的指针地址-0x7ffeecd84940 

 copyMutabelStrOne-copy-的指针地址-0x7ffeecd84938   

  copyMutabelStrTwo-Mutable-的指针地址-0x7ffeecd84930 

从上面的结果我们可以知道: 

1、非集合类 

不可变非集合类的对象copy: 指针拷贝,共同内存 

不可变的非集合类的对象mutableCopy:是对内容的的拷贝,创建了新的内存空间。 

可变的非集合类的对象copy:是对内容的拷贝,创建的新的内存空间 

可变的非集合类的对象mutableCopy:是对内容的拷贝,创建的新的内存空间 

2、集合类的 

不可变集合类的对象copy: 指针拷贝,共同内存 

不可变的集合类的对象mutableCopy:是对内容的的拷贝,创建了新的内存空间。 

可变的集合类的对象copy:是对内容的拷贝,创建的新的内存空间 

可变的集合类的对象mutableCopy:是对内容的拷贝,创建的新的内存空间

案例解析

我们先来分析一下,比如:小明喜欢看书,就买了一本《小王子》的书。 

代码如下: 

人物类的代码

#import "PrototypePerson.h"

@interface PrototypePerson ()

@property(nonatomic,strong)NSMutableArray *bookArray;

@property(nonatomic,copy)NSString *name;

/*

 *init方法

 */

- (instancetype)initWithName:(NSString *)name;

/*

 *添加书

 */

-(void)addBook:(NSString *)bookName;



@end



@implementation PrototypePerson

- (instancetype)initWithName:(NSString *)name

{

    self = [super init];

    if (self) {

        _name = name;

        _bookArray = [[NSMutableArray alloc] initWithCapacity:20];



    }

    return self;

}



-(void)addBook:(NSString *)bookName{

    [_bookArray addObject:bookName];

}



@end

小明买书的代码

    //原型模式

    //平常模式

    PrototypePerson *prototypePersonOne = [[PrototypePerson alloc]initWithName:@"小明"];

    //小明买了本《小王子》的书

    [prototypePersonOne addBook:@"《小王子》"];



    //现在小黄,也买了一个书柜,也买了本《小王子》的书

    PrototypePerson *prototypePersonTwo = [[PrototypePerson alloc]initWithName:@"小黄"];

    [prototypePersonTwo addBook:@"《小王子》"];

然后小黄发现小明这本书很好,他就买了一本一摸一样的书。 

代码如下

 PrototypePerson *prototypePersonOne = [[PrototypePerson alloc]initWithName:@"小明"];

    //小明买了本《小王子》的书

    [prototypePersonOne addBook:@"《小王子》"];



    //现在小黄,也买了一个书柜,也买了本《小王子》的书

    PrototypePerson *prototypePersonTwo = [[PrototypePerson alloc]initWithName:@"小黄"];

    [prototypePersonTwo addBook:@"《小王子》"];

现在小明只有一本书,我们就只要添加一本书就行,如果过段时间小明有几百本书,这个时候小黄根据小明的书籍买了一摸一样的书籍,这个时候,我们还需要一本一本的书籍添加吗? 

这个时候原型模式就派上用场了。我们可以在我们人物类上面实现NSCopying协议,实现- (id)copyWithZone:(NSZone *)zone方法,这样就实现了小明这个人物的深拷贝。 

代码如下: 

人物类的代码:

#import "PrototypePerson.h"

@interface PrototypePerson ()<NSCopying>

@property(nonatomic,strong)NSMutableArray *bookArray;

@property(nonatomic,copy)NSString *name;

/*

 *init方法

 */

- (instancetype)initWithName:(NSString *)name;

/*

 *添加书

 */

-(void)addBook:(NSString *)bookName;



@end



@implementation PrototypePerson

- (instancetype)initWithName:(NSString *)name

{

    self = [super init];

    if (self) {

        _name = name;

        _bookArray = [[NSMutableArray alloc] initWithCapacity:20];



    }

    return self;

}



-(void)addBook:(NSString *)bookName{

    [_bookArray addObject:bookName];

}



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

    PrototypePerson *prototypePerson = [[[self class] allocWithZone:zone]initWithName:_name];

    prototypePerson.bookArray = [_bookArray mutableCopy];

    return prototypePerson;



}

@end
//对小明人物类的深拷贝



    //原型模式



    PrototypePerson *prototypePersonOne = [[PrototypePerson alloc]initWithName:@"小明"];

    //小明买了本《小王子》的书

    [prototypePersonOne addBook:@"《小王子》"];





    //如果,以后小明买了很多本书,过了一段时间,小黄,和他买了一摸一样的书籍,这个时候就可以使用原型模式,实现NSCopying协议,实现- (id)copyWithZone:(NSZone *)zone方法来实现对象的拷贝。

    //小黄

    PrototypePerson *prototypePersonThree =[prototypePersonOne copy];

//小黄发现了一本很好的书

    [prototypePersonThree addBook:@"《睡前故事》"];



    NSLog(@"小明内存地址 ---- %p \n 小黄内存地址 -----%p",prototypePersonOne,prototypePersonThree);
我们来打印一下,小明和小黄的内存地址和购买的书籍数据



2018-06-12 16:36:49.541459+0800 DesignDemo[19613:790893] 小明内存地址 ---- 0x600000237700 

 小黄内存地址 -----0x6000002373e0

2018-06-12 16:36:49.541741+0800 DesignDemo[19613:790893] 小明的书籍 ---- (

    "\U300a\U5c0f\U738b\U5b50\U300b"

) 

 小黄内存书籍 -----(

    "\U300a\U5c0f\U738b\U5b50\U300b",

    "\U300a\U7761\U524d\U6545\U4e8b\U300b"

根据上面的结果,我们发现小明和小黄的内存地址不一样,说明实现了深拷贝,小明和小黄豆是购买了《小王子》这本书籍,小黄还买了本《睡前故事》。

总结

如果有写的不正确或者侵权的,希望大家给我提出来,我会及时修改。谢谢大家。

--------------------- 

作者:小雅_yyq 

原文:https://blog.csdn.net/u014644610/article/details/80668017 


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

精通Android游戏开发

精通Android游戏开发

[美] Vladimir Silva / 王恒、苏金国 等 / 人民邮电出版社 / 2011-2 / 45.00元

作为引领移动技术潮流的软件平台,Android发布了NDK以支持Java和C的混合开发,使PC游戏可以在Android平台上焕发更多魅力。 本书是为那些在Android游戏开发工作中寻求突破的人准备的。书中不仅通过Space Blaster和Asteroids这两个炫酷 的街机游戏深入介绍了如何从头构建纯Java游戏,更详细展示了如何将PC上的3D经典游戏Doom和Wolfenstein 3......一起来看看 《精通Android游戏开发》 这本书的介绍吧!

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具