23種設(shè)計(jì)模式(八)

版本記錄

版本號(hào) 時(shí)間
V1.0 2017.04.28

前言

前面講了23種設(shè)計(jì)模式中的前幾個(gè),下面我們繼續(xù),先看前幾篇文章。
1. 23種設(shè)計(jì)模式(一)
2. 23種設(shè)計(jì)模式(二)
3. 23種設(shè)計(jì)模式(三)
4. 23種設(shè)計(jì)模式(四)
5. 23種設(shè)計(jì)模式(五)
6. 23種設(shè)計(jì)模式(六)
7. 23種設(shè)計(jì)模式(七)

詳述

十五、迭代器模式——Iterator

??提供一種方法順序訪問一個(gè)聚合對(duì)象中的各個(gè)元素,而又不暴露該對(duì)象的內(nèi)部表示。OC中迭代器已經(jīng)實(shí)現(xiàn)的很完美了。我簡單的舉幾個(gè)例子。

1. 迭代器

    NSArray *arr = [NSArray arrayWithObjects:@"bei", @"jing", @"huan", @"ying", @"nin", nil];
    NSDictionary *dic = [NSDictionary dictionaryWithObjectsAndKeys:@"value1", @"key1", @"value2", @"key2", nil];
        
    // 創(chuàng)建數(shù)組 正序 迭代器
    NSEnumerator *arrEnumer1 = [arr objectEnumerator];
        
    // 創(chuàng)建數(shù)組 反序 迭代器
    NSEnumerator *arrEnumer2 = [arr reverseObjectEnumerator];
        
    // 創(chuàng)建字典 key 迭代器
    NSEnumerator *dicKeyEnumer = [dic keyEnumerator];
        
    // 創(chuàng)建字典 對(duì)象 迭代器
    NSEnumerator *dicObjEnumer = [dic objectEnumerator];
        
    // 獲取迭代器中下一個(gè)對(duì)象
    id obj = [arrEnumer1 nextObject];
        
    // 獲取迭代器中所有對(duì)象
    NSArray *array = [arrEnumer2 allObjects];




2. 數(shù)組用迭代器遍歷
    NSArray *array = [NSArray arrayWithObjects:@"bei", @"jing", @"huan", @"ying", @"nin", nil];
        
    // 獲取數(shù)組的正序迭代器
    NSEnumerator *enu1 = [array objectEnumerator];
        
    // 獲取數(shù)組的反序迭代器
    NSEnumerator *enu2 = [array reverseObjectEnumerator];
        
    // 遍歷數(shù)組
    id obj = nil;
        
    // 正序,獲取下一個(gè)需要遍歷的元素
    while (obj = [enu1 nextObject]) {
        NSLog(@"%@", obj);
    }
        
    // 反序,獲取下一個(gè)需要遍歷的元素
    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]);
    }
        
    // 對(duì)象迭代器
    NSEnumerator *objEnumer = [dic objectEnumerator];
        
    id obj = nil;
    while (obj = [objEnumer nextObject]) {
        NSLog(@"%@", obj);
    }


結(jié)論:直接看代碼體會(huì),都能看懂。


十六、單例模式——Singleton

??保證一個(gè)類僅有一個(gè)實(shí)例,使它們都可以獨(dú)立地變化。

我先說一下我們自定義的單例,先看代碼。


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


??上面的是我們自定義的單例。 就我本身理解而言,我認(rèn)為的單例在整個(gè)工程中,就相當(dāng)于一個(gè)全局變量,不論在哪里需要用到這個(gè)類的實(shí)例變量,都可以通過單例方法來取得,而且一旦你創(chuàng)建了一個(gè)單例類,不論你在多少個(gè)界面中初始化調(diào)用了這個(gè)單例方法取得對(duì)象,它們所有的對(duì)象都是指向的同一塊內(nèi)存存儲(chǔ)空間(即單例類保證了該類的實(shí)力對(duì)象是唯一存在的一個(gè))?!皢卫J健笔俏覀?cè)趇OS中最常使用的設(shè)計(jì)模式之一。單例模式不需要傳遞任何參數(shù),就有效地解決了不同代碼間的數(shù)據(jù)共享問題。

??ios中還有很多系統(tǒng)的單例,比如NSUserDefaults就是單例,UIApplication類有一個(gè)方法叫sharedApplication也是一個(gè)單例,NSNotificationCenter(消息中心) 、NSFileManager(文件管理) 、NSURLCache(請(qǐng)求緩存)、NSHTTPCookieStorage(應(yīng)用程序cookies池)都是系統(tǒng)單例。

下面我們就說一下單例的實(shí)現(xiàn)方式。

1.通過線程加鎖實(shí)現(xiàn)

 +(DBManager *)sharedManager;    (.h文件中)
 
 // m文件中的實(shí)現(xiàn):
 + (DBManager *)sharedManager{
  Static DBManager *manager = nil;
  @synchronized(self){
  if(manager == nil){
    manager = [[DBManager alloc]init];
     }
   }
  return manager;
}

2. 通過GCD實(shí)現(xiàn)單例方法:

+(DBManager *)sharedManager;    (.h文件中)
 
 //.m文件中的實(shí)現(xiàn):
 + (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試圖獲得一個(gè)新實(shí)例的時(shí)候不產(chǎn)生一個(gè)新實(shí)例,
+ (id)allocWithZone:(NSZone *)zone{
    @synchronized(self){
        if (!manager) {
            manager = [super allocWithZone:zone]; //確保使用同一塊內(nèi)存地址
            return manager;
        }
        return nil;
    }
}

4. 適當(dāng)實(shí)現(xiàn)copyWithZone,release和autorelease。


-  (id)init;
{
    @synchronized(self) {
        if (self = [super init]){
            return self;
        }
        return nil;
    }
}


下面就集中說一下ARC和非ARC下的單例模式設(shè)計(jì)。

1. ARC中單例設(shè)計(jì)模式

//.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會(huì)調(diào)用allocWithZone:
+  (instancetype)allocWithZone:(struct _NSZone *)zone
{
    //只進(jìn)行一次
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _instance = [super allocWithZone:zone];
    });
    return _instance;
}

//初始化方法
-  (instancetype)init
{
    // 只進(jìn)行一次
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _instance = [super init];
    });
    return _instance;
}

//copy在底層 會(huì)調(diào)用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下的單例模式設(shè)計(jì)
//.m文件

#import <Foundation/Foundation.h>

//單例方法
@interface Singleton : NSObject

+ (instancetype)sharedSingleton;

@end

//.m文件

#import "Singleton.h"

@implementation Singleton
//全局變量
static id _instance = nil;

//單例方法
+(instancetype)sharedSingleton
{
    //系統(tǒng)的大多數(shù)類方法都有做autorelease,所以我們也需要做一下
     return [[[self alloc] init] autorelease];
}

//alloc會(huì)調(diào)用allocWithZone:
+ (instancetype)allocWithZone:(struct _NSZone *)zone
{
    //只進(jìn)行一次
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _instance = [super allocWithZone:zone];
    });
    return _instance;
}

//初始化方法
- (instancetype)init
{
    // 只進(jìn)行一次
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _instance = [super init];
    });
    return _instance;
}

- (oneway void)release
{
    //什么都不做 保證單例對(duì)象不被銷毀
}

//返回本身 保證只有一個(gè)單例對(duì)象
- (instancetype)retain
{
    return _instance;
} 

//計(jì)數(shù)器為1 保證只有一個(gè)單例對(duì)象
-  (NSUInteger)retainCount
{
    return 1;
}

//copy在底層 會(huì)調(diào)用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



后記

未完,待續(xù),休息了,謝謝大家。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容