(一二三)基於GCD的dispatch_once實現單例設計
阿新 • • 發佈:2017-05-12
super dispatch ret 強引用 一次 nslog span imp int
通過這樣的方式,簡單高效的實現了單例,值得使用。
要實現單例,關鍵是要保證類的alloc和init僅僅被調用一次。而且被自身強引用防止釋放。
近日讀唐巧先生的《iOS開發進階》。受益匪淺,通過GCD實現單例就是收獲之中的一個,以下把這種方法與大家分享。
在GCD中,有一個函數dispatch_once,能夠實現代碼段的一次性運行,和static修飾的變量賦值的一次性一樣。我們結合static和dispatch_once,就能夠簡單的實現單例。
以下的代碼實現了SomeClass單例:
#import <Foundation/Foundation.h> @interface SomeClass : NSObject + (SomeClass *)sharedInstance; @end
#import "SomeClass.h" @implementation SomeClass + (SomeClass *)sharedInstance{ static id sharedInstance = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ sharedInstance = [[self alloc] init]; }); return sharedInstance; } @end以下解釋一下這段代碼。
第一句新建一個sharedInstance靜態強指針,是為了指向創建好的單例,防止其釋放,僅僅有第一次進入的時候指針被賦值為nil。
一定註意dispatch_once_t變量必須是靜態,它的值用於推斷是否已經運行一次。
第二句和dispatch_once是固定使用方法,這樣能夠實現block內的代碼一次性運行。也就是說僅僅有第一次調用這種方法時才會實例化類。之後都是返回指針指向的值。
最後返回指針,就相當於拿到了單例。
對單例的執行結果進行驗證:
我們多次獲取單例對象而且打印地址,能夠發現地址是一樣的。
#import "ViewController.h" #import "SomeClass.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; SomeClass *sc1 = [SomeClass sharedInstance]; SomeClass *sc2 = [SomeClass sharedInstance]; SomeClass *sc3 = [SomeClass sharedInstance]; NSLog(@"%p %p %p",sc1,sc2,sc3); } @end
2015-08-17 20:59:22.139 基於GCD實現單例[2785:31918] 0x7fb40af11b90 0x7fb40af11b90 0x7fb40af11b90
通過這樣的方式,簡單高效的實現了單例,值得使用。
(一二三)基於GCD的dispatch_once實現單例設計