單例模式能夠說是每一個應用都有用到的一個模式,在iOS的世界裏更是常見。例如咱們的UIApplication sharedApplicaiton應用的就是單利模式, defaultManager和defaultCenter等也是常見的單利。這也是爲何人們常常把CoreData的實例變量放在UIApplication裏面。 html
對單例有了更清楚的瞭解之後,咱們能夠讓咱們的代碼更加清晰。好比,咱們能夠把放在AppDelegate裏的關於CoreData的代碼移植到其餘的單例類裏面。 安全
在相關網絡博客上面看到了下面三種實現單利的方法。 網絡
1. 使用GCD實現單線程實現(給一篇參考文章http://bj007.blog.51cto.com/1701577/649413) app
void dispatch_once( dispatch_once_t *predicate, dispatch_block_t block);其中第一個參數predicate,該參數是檢查後面第二個參數所表明的代碼塊是否被調用的謂詞,第二個參數則是在整個應用程序中只會被調用一次的代碼塊。dispach_once函數中的代碼塊只會被執行一次,並且仍是線程安全。 函數
@implementation MyClass #pragma mark Singleton Methods + (id)sharedClass { static MyClass *sharedMyClass = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ sharedMyClass = [[self alloc] init]; }); return sharedMyClass; } @end2. 加上同步
+ (id)sharedClass { static MyClass *sharedMyClass = nil; @synchronized(self) { if (sharedMyClass == nil) sharedMyClass = [[self alloc] init]; } return sharedMyClass; }
3. 沒有ARC的同步實現(官網給出的也是這種方式 http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CocoaFundamentals/CocoaObjects/CocoaObjects.html#//apple_ref/doc/uid/TP40002974-CH4-SW32) ui
+ (id)sharedClass { @synchronized(self) { if(sharedMyClass == nil) sharedMyClass = [[super allocWithZone:NULL] init]; } return sharedMyClass; } + (id)allocWithZone:(NSZone *)zone { return [[self sharedMyClass] retain]; } - (id)copyWithZone:(NSZone *)zone { return self; } - (id)retain { return self; } - (unsigned)retainCount { return UINT_MAX; } - (oneway void)release { // never release } - (id)autorelease { return self; }4. 其實還有其餘的方式來實現。好比你將同步的代碼快寫到一個SynthesizeSingleton.h的頭文件裏。
#define SYNTHESIZE_SINGLETON_FOR_CLASS(classname) \ \ static classname *shared##classname = nil; \ \ + (classname *)shared##classname \ { \ @synchronized(self) \ { \ if (shared##classname == nil) \ { \ shared##classname = [[self alloc] init]; \ } \ } \ \ return shared##classname; \ } \ \ + (id)allocWithZone:(NSZone *)zone \ { \ @synchronized(self) \ { \ if (shared##classname == nil) \ { \ shared##classname = [super allocWithZone:zone]; \ return shared##classname; \ } \ } \ \ return nil; \ } \ \ - (id)copyWithZone:(NSZone *)zone \ { \ return self; \ } \ \在相關的類
@interface Preference : NSObject + (Preference *)sharedPreference;
在類的實現里加上 spa
#import "SynthesizeSingleton.h" @implementation Preference SYNTHESIZE_SINGLETON_FOR_CLASS(Preference);
這種方式無疑是最簡單也最易複用的方式。使用的時候直接調用shareXxx就能夠了。 線程