原型模式的解析-iOS

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

内容简介:原型模式的解析-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 


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

查看所有标签

猜你喜欢:

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

DOM Scripting

DOM Scripting

Jeremy Keith / friendsofED / 2010-12 / GBP 27.50

There are three main technologies married together to create usable, standards-compliant web designs: XHTML for data structure, Cascading Style Sheets for styling your data, and JavaScript for adding ......一起来看看 《DOM Scripting》 这本书的介绍吧!

MD5 加密
MD5 加密

MD5 加密工具

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具