美文网首页23种设计模式
23种设计模式(八)

23种设计模式(八)

作者: 刀客传奇 | 来源:发表于2017-04-28 01:24 被阅读22次

    版本记录

    版本号 时间
    V1.0 2017.04.28

    前言

    前面讲了23种设计模式中的前几个,下面我们继续,先看前几篇文章。
    1. 23种设计模式(一)
    2. 23种设计模式(二)
    3. 23种设计模式(三)
    4. 23种设计模式(四)
    5. 23种设计模式(五)
    6. 23种设计模式(六)
    7. 23种设计模式(七)

    详述

    十五、迭代器模式——Iterator

      提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露该对象的内部表示。OC中迭代器已经实现的很完美了。我简单的举几个例子。

    1. 迭代器
    
    
        NSArray *arr = [NSArray arrayWithObjects:@"bei", @"jing", @"huan", @"ying", @"nin", nil];
        NSDictionary *dic = [NSDictionary dictionaryWithObjectsAndKeys:@"value1", @"key1", @"value2", @"key2", nil];
            
        // 创建数组 正序 迭代器
        NSEnumerator *arrEnumer1 = [arr objectEnumerator];
            
        // 创建数组 反序 迭代器
        NSEnumerator *arrEnumer2 = [arr reverseObjectEnumerator];
            
        // 创建字典 key 迭代器
        NSEnumerator *dicKeyEnumer = [dic keyEnumerator];
            
        // 创建字典 对象 迭代器
        NSEnumerator *dicObjEnumer = [dic objectEnumerator];
            
        // 获取迭代器中下一个对象
        id obj = [arrEnumer1 nextObject];
            
        // 获取迭代器中所有对象
        NSArray *array = [arrEnumer2 allObjects];
    
    
    
    
    
    2. 数组用迭代器遍历
    
        NSArray *array = [NSArray arrayWithObjects:@"bei", @"jing", @"huan", @"ying", @"nin", nil];
            
        // 获取数组的正序迭代器
        NSEnumerator *enu1 = [array objectEnumerator];
            
        // 获取数组的反序迭代器
        NSEnumerator *enu2 = [array reverseObjectEnumerator];
            
        // 遍历数组
        id obj = nil;
            
        // 正序,获取下一个需要遍历的元素
        while (obj = [enu1 nextObject]) {
            NSLog(@"%@", obj);
        }
            
        // 反序,获取下一个需要遍历的元素
        while (obj = [enu2 nextObject]) {
            NSLog(@"%@", obj);
        }
    
    
    
    3. 集合用迭代器
    
        NSSet *set = [NSSet setWithObjects:@5, @23, @3, @8, @21, @33, @18, nil];
            
        NSEnumerator *enu = [set objectEnumerator];
            
        id obj = nil;
            
        while (obj = [enu nextObject]) {
            NSLog(@"%@", obj);
        }
    
    
    
    
    4. 字典用迭代器
    
    
        NSDictionary *dic = [NSDictionary dictionaryWithObjectsAndKeys:@"value1", @"key1", @"value2", @"key2", nil];
            
        // key 迭代器
        NSEnumerator *keyEnumer = [dic keyEnumerator];
            
        id key = nil;
        while (key = [keyEnumer nextObject]) {
            NSLog(@"%@ = %@", key, [dic objectForKey:key]);
        }
            
        // 对象迭代器
        NSEnumerator *objEnumer = [dic objectEnumerator];
            
        id obj = nil;
        while (obj = [objEnumer nextObject]) {
            NSLog(@"%@", obj);
        }
    
    
    

    结论:直接看代码体会,都能看懂。


    十六、单例模式——Singleton

      保证一个类仅有一个实例,使它们都可以独立地变化。

    我先说一下我们自定义的单例,先看代码。

    
    1. HCDSingleton.h
    
    
    #import <Foundation/Foundation.h>
    
    @interface HCDSingleton : NSObject
    
    + (instancetype)sharedInstance;
    
    @end
    
    
    2. HCDSingleton.m
    
    #import "HCDSingleton.h"
    
    @implementation HCDSingleton
    
    + (instancetype)sharedInstance
    
    {
        static HCDSingleton *singleton = nil;
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            singleton = [[HCDSingleton alloc]init];
        });
        return singleton;
    }
    
    @end
    
    
    

      上面的是我们自定义的单例。 就我本身理解而言,我认为的单例在整个工程中,就相当于一个全局变量,不论在哪里需要用到这个类的实例变量,都可以通过单例方法来取得,而且一旦你创建了一个单例类,不论你在多少个界面中初始化调用了这个单例方法取得对象,它们所有的对象都是指向的同一块内存存储空间(即单例类保证了该类的实力对象是唯一存在的一个)。“单例模式”是我们在iOS中最常使用的设计模式之一。单例模式不需要传递任何参数,就有效地解决了不同代码间的数据共享问题。

      ios中还有很多系统的单例,比如NSUserDefaults就是单例,UIApplication类有一个方法叫sharedApplication也是一个单例,NSNotificationCenter(消息中心) 、NSFileManager(文件管理) 、NSURLCache(请求缓存)、NSHTTPCookieStorage(应用程序cookies池)都是系统单例。

    下面我们就说一下单例的实现方式。

    1.通过线程加锁实现
    
    
     +(DBManager *)sharedManager;    (.h文件中)
     
     // m文件中的实现:
     + (DBManager *)sharedManager{
      Static DBManager *manager = nil;
      @synchronized(self){
      if(manager == nil){
        manager = [[DBManager alloc]init];
         }
       }
      return manager;
    }
    
    
    2. 通过GCD实现单例方法:
    
    
    +(DBManager *)sharedManager;    (.h文件中)
     
     //.m文件中的实现:
     + (DBManager *)sharedManager{
      Static DBManager *manager = nil;
          static dispatch_once_t token;
          dispatch_once(&token,^{
                  if(manager == nil){
               manager = [[DBManager alloc]init];
            }
       } );
      return manager;
    }
    
    
    
    3.  重写allocWithZone方法,用来保证其他人直接使用alloc和init试图获得一个新实例的时候不产生一个新实例,
    
    + (id)allocWithZone:(NSZone *)zone{
        @synchronized(self){
            if (!manager) {
                manager = [super allocWithZone:zone]; //确保使用同一块内存地址
                return manager;
            }
            return nil;
        }
    }
    
    
    4. 适当实现copyWithZone,release和autorelease。
    
    
    
    -  (id)init;
    {
        @synchronized(self) {
            if (self = [super init]){
                return self;
            }
            return nil;
        }
    }
    
    
    

    下面就集中说一下ARC和非ARC下的单例模式设计。

    1. ARC中单例设计模式
    
    
    //.h文件
    #import <Foundation/Foundation.h>
    
    @interface Singleton : NSObject
    
    //单例方法
    +(instancetype)sharedSingleton;
    
    @end
    
    //.m文件
    #import "Singleton.h"
    
    @implementation Singleton
    
    //全局变量
    static id _instance = nil;
    
    //单例方法
    +  (instancetype)sharedSingleton
    {
        return [[self alloc] init];
    }
    
    //alloc会调用allocWithZone:
    +  (instancetype)allocWithZone:(struct _NSZone *)zone
    {
        //只进行一次
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            _instance = [super allocWithZone:zone];
        });
        return _instance;
    }
    
    //初始化方法
    -  (instancetype)init
    {
        // 只进行一次
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            _instance = [super init];
        });
        return _instance;
    }
    
    //copy在底层 会调用copyWithZone:
    
    -  (id)copyWithZone:(NSZone *)zone
    {
        return  _instance;
    }
    +  (id)copyWithZone:(struct _NSZone *)zone
    {
        return  _instance;
    }
    +  (id)mutableCopyWithZone:(struct _NSZone *)zone
    {
        return _instance;
    }
    -  (id)mutableCopyWithZone:(NSZone *)zone
    {
        return _instance;
    }
    
    @end
    
    
    
    
    
    2. 非ARC下的单例模式设计
    
    //.m文件
    
    #import <Foundation/Foundation.h>
    
    //单例方法
    @interface Singleton : NSObject
    
    + (instancetype)sharedSingleton;
    
    @end
    
    //.m文件
    
    #import "Singleton.h"
    
    @implementation Singleton
    //全局变量
    static id _instance = nil;
    
    //单例方法
    +(instancetype)sharedSingleton
    {
        //系统的大多数类方法都有做autorelease,所以我们也需要做一下
         return [[[self alloc] init] autorelease];
    }
    
    //alloc会调用allocWithZone:
    + (instancetype)allocWithZone:(struct _NSZone *)zone
    {
        //只进行一次
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            _instance = [super allocWithZone:zone];
        });
        return _instance;
    }
    
    //初始化方法
    - (instancetype)init
    {
        // 只进行一次
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            _instance = [super init];
        });
        return _instance;
    }
    
    - (oneway void)release
    {
        //什么都不做 保证单例对象不被销毁
    }
    
    //返回本身 保证只有一个单例对象
    - (instancetype)retain
    {
        return _instance;
    } 
    
    //计数器为1 保证只有一个单例对象
    -  (NSUInteger)retainCount
    {
        return 1;
    }
    
    //copy在底层 会调用copyWithZone:
    + (id)copyWithZone:(struct _NSZone *)zone
    {
        return  _instance;
    }
    - (id)copyWithZone:(NSZone *)zone
    {
        return _instance;
    }
    + (id)mutableCopyWithZone:(struct _NSZone *)zone
    {
        return _instance;
    }
    - (id)mutableCopyWithZone:(NSZone *)zone
    {
        return _instance;
    }
    @end
    
    
    
    

    后记

    未完,待续,休息了,谢谢大家。

    相关文章

      网友评论

        本文标题:23种设计模式(八)

        本文链接:https://www.haomeiwen.com/subject/lqqozttx.html