之前太過於年輕,總結的簡單單例模式傳送門: http://www.cnblogs.com/PSSSCode/p/5482419.html
這篇博客主要講的是GCD中的單例模式,大家肯定會想到dispatch_once這個函數,但是這篇博客不僅僅是dispatch_once的使用。
1、單例模式簡介(面試常考的。。。)
- 單例模式的作用
- 可以保證在程序運行過程,一個類只有一個實例,而且該實例易於供外界訪問
- 從而方便地控制了實例個數,並節約系統資源
- 單例模式的使用場合
- 系統
- UIApplication、NSUserDefaults、NSFileManager、NSNoticationCenter
- 自定義
- 在某個應用程序中,共享一份資源(這份資源只需要創建初始化一次)
- 網絡計數器
- 分享界面、登錄界面、評論界面不登錄會跳轉到唯一界面登錄界面(單例實現)
- 點擊跳轉,控制器設置為單例,該控制器不會被銷毀,依然存在內存中,返回再次回去,再點擊進來,則會快速進入不會創建對應的新的控制器
2、具體代碼
- 只需實現三個方法
- 1、allocWithZone: (alloc底層調用該方法)
- 2、shareCar (一種命名規范)
- 3、copyWithZone (對應實例變量 調用copy會調用該方法)
默認情況
添加單例情況
1 @interface PSSCar() // <NSCopying> 2 3 @end 4 5 @implementation PSSCar 6 7 static PSSCar *_car; 8 9 + (instancetype)allocWithZone:(struct _NSZone *)zone 10 { 11 static dispatch_once_t onceToken; 12 dispatch_once(&onceToken, ^{ 13 _car = [super allocWithZone:zone]; 14 }); 15 return _car; 16 } 17 18 + (instancetype)sharedCar 19 { 20 static dispatch_once_t onceToken; 21 dispatch_once(&onceToken, ^{ 22 _car = [[self alloc] init]; 23 }); 24 return _car; 25 } 26 27 - (id)copyWithZone:(NSZone *)zone 28 { 29 return _car; 30 }
3、封裝代碼
當一個項目中多個類需要使用單例,則需要在對應類的.m文件中寫以上的代碼,並且代碼幾乎沒有差別,所有可以將上面的代碼封裝成一個工具類,並在工具類中使用宏定義,減少代碼冗余。
// .h文件 #define PSSSingletonH(name) + (instancetype)shared##name; // .m文件 #define PSSSingletonM(name) \ static id _instance; \ \ + (instancetype)allocWithZone:(struct _NSZone *)zone \ { \ static dispatch_once_t onceToken; \ dispatch_once(&onceToken, ^{ \ _instance = [super allocWithZone:zone]; \ }); \ return _instance; \ } \ \ + (instancetype)shared##name \ { \ static dispatch_once_t onceToken; \ dispatch_once(&onceToken, ^{ \ _instance = [[self alloc] init]; \ }); \ return _instance; \ } \ \ - (id)copyWithZone:(NSZone *)zone \ { \ return _instance; \ }
在對應類的.h和.m中只需要調用宏定義重新命名的響應方法即可,同時將本類的類名傳入,即可實現快速單例模式的實現與使用