23种设计模式(八)

版本记录

版本号 时间
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 

@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 

@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 

//单例方法
@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种设计模式(八)_第1张图片

你可能感兴趣的:(23种设计模式(八))