標籤:style blog color 使用 檔案 資料
單例是一種重要的概念,它是一種極其便利的設計模式。在iPhone SDK中大量使用了單例的概念,例如,UIApplication的sharedApplication方法,任何時候都會返回一個當前應用程式的UIApplication執行個體。
有時候我們在一個程式幾乎所有的地方都要使用某一資料並且要對其進行操作並且這個資料是單一的,全域只需要一個,這種情況下我們也許就會使用單例了
雖然單例很好用,但是不要濫用,因為單例會再程式運行過程中一直存在,不會被銷毀(相當於直接在記憶體上扒了一塊下來)
之前公司的航空項目中,使用者訂票時用的日期,等相關資訊最好使用單例,電商APP中的購物車應該也是用的單例
下面就說說怎麼建立一個單例===========因為現在有很多老項目是MRC的,也會用到單例隨意這裡也會給出MRC下單例的建立方法
1、為單例對象實現一個靜態執行個體,並初始化,然後設定成nil,
2、實現一個執行個體構造方法檢查上面聲明的靜態執行個體是否為nil,如果是則建立並返回一個本類的執行個體,
3、重寫allocWithZone方法,用來保證其他人直接使用alloc和init試圖獲得一個新實力的時候不產生一個新執行個體,
4、適當實現allocWitheZone,copyWithZone,release和autorelease(ARC下不需要事先release等MRC下特有的方法)
單當我們項目中有多個需要實現的單例類時,出了類名不一樣其他的基本都一樣,所以我們最好將單例抽取成一個宏
下面就是這個宏
// .h檔案的實現#define SingletonH(methodName) + (instancetype)shared##methodName;// .m檔案的實現#if __has_feature(objc_arc) // 是ARC#define SingletonM(methodName) static id _instace = nil; + (id)allocWithZone:(struct _NSZone *)zone { if (_instace == nil) { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ _instace = [super allocWithZone:zone]; }); } return _instace; } - (id)init { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ _instace = [super init]; }); return _instace; } + (instancetype)shared##methodName { return [[self alloc] init]; } + (id)copyWithZone:(struct _NSZone *)zone { return _instace; } + (id)mutableCopyWithZone:(struct _NSZone *)zone { return _instace; }#else // 不是ARC#define SingletonM(methodName) static id _instace = nil; + (id)allocWithZone:(struct _NSZone *)zone { if (_instace == nil) { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ _instace = [super allocWithZone:zone]; }); } return _instace; } - (id)init { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ _instace = [super init]; }); return _instace; } + (instancetype)shared##methodName { return [[self alloc] init]; } - (oneway void)release { } - (id)retain { return self; } - (NSUInteger)retainCount { return 1; } + (id)copyWithZone:(struct _NSZone *)zone { return _instace; } + (id)mutableCopyWithZone:(struct _NSZone *)zone { return _instace; }#endif
裡面用has_feature來判斷有沒有使用ARC,這樣引入這個宏的時候你就不用擔心是ARC還是非ARC了
只需要在實現單例的.h檔案寫上
SingletonH(methodName)
在.m檔案裡面寫上
SingletonM(methodName)