要實作單例,關鍵是要保證類的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
通過這種方式,簡單高效的實作了單例,值得使用。