這裏不講單例模式的用途了,下面的代碼,主要都會在.m文件的代碼。
多線程
#import "SingletonClass.h" @implementation SingletonClass + (SingletonClass *)shareSingletonClass { SingletonClass* singleton = [[SingletonClass alloc] init]; return singleton; } @end
這裏定義了一個類方法shareSingletonClass,這個單例類會調用這個方法獲得全局惟一實例,但顯然如今還達不到生成全局惟一實例的效果,每次調用這個方法都會生成一個新的實例。併發
再次修改:
高併發
#import "SingletonClass.h" static SingletonClass* singleton = nil; @implementation SingletonClass + (SingletonClass *)shareSingletonClass { if (singleton == nil) { singleton = [[SingletonClass alloc] init]; } return singleton; } @end
這裏生成了一個靜態的SingletonClass實例,而後判斷若是這個實例沒有被建立,就建立,不然直接返回這個實例。
性能
但這種作法只適合單線程,多線程的狀況下,各個線程在最開始都會判斷到singleton=nil,會生成多個singleton實例。因此這時候須要線程鎖:優化
+ (SingletonClass *)shareSingletonClass { @synchronized(self) { if (singleton == nil) { singleton = [[SingletonClass alloc] init]; } } return singleton; }
這樣子已經完成一個單例了。
spa
可是在有高併發線程的狀況下,每次都要作if判斷,是很耗性能的,在線程鎖裏面的代碼,是越少越好,而咱們真正所須要的是singleton = [[SingletonClass alloc] init];這句代碼,因此能夠把線程鎖移到if判斷裏面。線程
+ (SingletonClass *)shareSingletonClass { if (singleton == nil) { @synchronized(self) { singleton = [[SingletonClass alloc] init]; } } return singleton; }
但這樣在多線程下,新線程仍是會近到線程鎖裏面,生成新的實例,因此仍是要再作一層判斷:
code
+ (SingletonClass *)shareSingletonClass { if (singleton == nil) { @synchronized(self) { if (singleton == nil) { singleton = [[SingletonClass alloc] init]; } } } return singleton; }
第一個if判斷,使得只有在實例沒被建立後,纔會進到線程鎖裏面,減小進入線程鎖判斷;第二個判斷,是多線程的時候的判斷,進到這裏的概率已經少了不少了。這種是多層線程鎖。
it
事實上,在OBJC裏面,對於單例,已經爲咱們準備好了方法:io
+ (SingletonClass *)shareSingletonClass { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ singleton = [[SingletonClass alloc] init]; }); return singleton; }
系統的方法,通常是被優化到最佳的,因此推薦使用這種方法。