能夠保證的程序運行過程,一個類只有一個示例,並且該實例易於供外界訪問設計模式
從而方便地控制了實例個數,並節約系統資源。安全
類只能有一個實例,而且必須從一個爲人數值的訪問點對其訪問。框架
這個惟一的實例只能經過子類化進行拓展,而且拓展的對象不會破壞客戶端代碼。學習
能夠用宏判斷是否爲ARC環境spa
#if _has_feature(objc_arc)#else//MRC#endif
ARC中單例模式的實現.net
在 .m中保留一個全局的static的實例線程
static id _instance; //重寫allocWithZone:方法,在這裏建立惟一的實例(注意線程安全) + (instancetype)allocWithZone:(struct _NSZone *)zone { @synchronized(self) { if (_instance == nil) { _instance = [super allocWithZone:zone]; } } return _instance; }
提供1個類方法讓外界訪問惟一的實例設計
+ (instancetype)sharedInstanceTool{ @synchronized(self){ if(_instance == nil){ _instance = [[self alloc] init]; } } return _instance; }
實現copyWithZone:方法指針
-(id)copyWithZone:(struct _NSZone *)zone{ return _instance; }
sharedInstanceTool
,首先檢查類的惟一實例是否已經建立,若是就會建立實例並將其返回。而之因此調用super而不是self,是由於已經在self中重載了基本的對象分配的方法,須要借用父類的功能來幫助處理底層內存的分配。allocWithZone:(struct _NSZone*)zone
方法中,只是返回從sharedInstanceTool
方法返回的類實例。而一樣的在Cocoa框架中調用allocWithZone:(struct _NSZone*)zone
會分配內存,引用計數會設置爲1,而後返回實例。一樣的重寫(id)copyWithZone:(struct _NSZone *)zone
方法,也是爲了保證不會返回實例的副本,而是返回self.返回同一個實例。+(instancetype)sharedInstance { static WMSingleton *singleton = nil; if (! singleton) { singleton = [[self alloc] initPrivate]; } return singleton; } - (instancetype)init { @throw [NSException exceptionWithName:@"這個是個單例" reason:@"應該這樣調用 [WMSingleton sharedInstance]" userInfo:nil]; return nil; }//實現本身真正的私有初始化方法- (instancetype)initPrivate { self = [super init]; return self; }
@synchronized
來添加了一個互斥鎖,以此來保證線程安全。而如今咱們開始嘗試用線程的方式來實現一個加單的單例。static WMObject *_instance; + (instancetype)allocWithZone:(struct _NSZone *)zone { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ _instance = [super allocWithZone:zone]; }); return _instance; } + (instancetype)sharedInstance { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ _instance = [[self alloc] init]; }); return _instance; } - (id)copyWithZone:(NSZone *)zone { return _instance; }
sharedInstanceTool
,首先檢查類的惟一實例是否已經建立,若是就會建立實例並將其返回。而略有不一樣的地方就是咱們此次經過dispatch_once_t
來保證線程的安全性。至於dispatch_once_t
的用法這裏就一一贅述了,線程的相關教程都會有其相關的描述。WMSingleton.h
// .h文件#define WMSingletonH(name) + (instancetype)shared##name; // .m文件#define WMSingletonM(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類//引入這個宏文件#import "WMSingleton.h"@interface WMObject : NSObjectWMSingletonH(object)@end//.m類@implementation WMObjectWMSingletonM(Car)@end
Cocoa Touch
框架中一樣存在着大量的單例模式讓咱們來學習,好比UIApplication
、UIAccelerometer
、以及NSFileManager
等等。因此在單例模式的學習上仍是依舊的任重道遠呀。。。