注:本文所有權歸作者所有,轉載請注明出處
當希望在一個應用程序中某個類的對象只能存在一個的時候就可以考慮用單例模式來實現,單例模式在C++中比較容易實現(只需把構造函數聲明為PRivate),而在Objective-C中對象可以通過NSObject的alloc來產生,所以需要編寫一些額外的代碼來確保對象的唯一性,考慮到現在編寫iOS APP代碼幾乎都是ARC方式,且GCD也已經被用爛了,故本文給出一種利用GCD技術來實現嚴格單例模式的ARC版本,具體代碼如下所示,所有的注意點都寫在了注釋里面:
1 Singleton.h 2 @interface Singleton : NSObject 3 @property(nonatomic,strong) NSString *name; 4 +(Singleton*)defaultManager; 5 @end 6 7 8 Singleton.m 9 @implementation Singleton10 //單例類的靜態實例對象,因對象需要唯一性,故只能是static類型11 static Singleton *defaultManager = nil;12 13 /**單例模式對外的唯一接口,用到的dispatch_once函數在一個應用程序內只會執行一次,且dispatch_once能確保線程安全14 */15 +(Singleton*)defaultManager16 {17 static dispatch_once_t token;18 dispatch_once(&token, ^{19 if(defaultManager == nil)20 {21 defaultManager = [[self alloc] init];22 }23 });24 return defaultManager;25 }26 27 /**覆蓋該方法主要確保當用戶通過[[Singleton alloc] init]創建對象時對象的唯一性,alloc方法會調用該方法,只不過zone參數默認為nil,因該類覆蓋了allocWithZone方法,所以只能通過其父類分配內存,即[super allocWithZone:zone]28 */29 +(id)allocWithZone:(struct _NSZone *)zone30 {31 static dispatch_once_t token;32 dispatch_once(&token, ^{33 if(defaultManager == nil)34 {35 defaultManager = [super allocWithZone:zone];36 }37 });38 return defaultManager;39 }40 //自定義初始化方法,本例中只有name這一屬性41 - (instancetype)init42 {43 self = [super init];44 if(self)45 {46 self.name = @"Singleton";47 }48 return self;49 }50 51 //覆蓋該方法主要確保當用戶通過copy方法產生對象時對象的唯一性52 - (id)copy53 {54 return self;55 }56 57 //覆蓋該方法主要確保當用戶通過mutableCopy方法產生對象時對象的唯一性58 - (id)mutableCopy59 {60 return self;61 }62 //自定義描述信息,用于log詳細打印63 - (NSString *)description64 {65 return [NSString stringWithFormat:@"memeory address:%p,property name:%@",self,self.name];66 }
測試代碼如下:
1 Singleton *defaultManagerSingleton =[Singleton defaultManager]; 2 NSLog(@"defaultManagerSingleton:/n%@",defaultManagerSingleton); 3 Singleton *allocSingleton = [[Singleton alloc] init]; 4 NSLog(@"allocSingleton:/n%@",allocSingleton); 5 Singleton *copySingleton = [allocSingleton copy]; 6 NSLog(@"copySingleton:/n%@",copySingleton); 7 Singleton *mutebleCopySingleton = [allocSingleton mutableCopy]; 8 NSLog(@"mutebleCopySingleton:/n%@",mutebleCopySingleton); 9 10 //打印結果11 2015-10-11 21:48:34.722 Singleton[1941:214584] defaultManagerSingleton:12 memeory address:0x7fa6d1591530,property name:Singleton13 2015-10-11 21:48:34.727 Singleton[1941:214584] allocSingleton:14 memeory address:0x7fa6d1591530,property name:Singleton15 2015-10-11 21:48:34.727 Singleton[1941:214584] copySingleton:16 memeory address:0x7fa6d1591530,property name:Singleton17 2015-10-11 21:48:34.727 Singleton[1941:214584] mutebleCopySingleton:18 memeory address:0x7fa6d1591530,property name:Singleton
從打印結果來看通過 [Singleton defaultManager]、[[Singleton alloc] init]、[allocSingleton copy]、[allocSingleton mutableCopy]這四種方法生成的對象地址都是0x7fa6d1591530,即表明對象是同一個,也就實現了嚴格單例模式,加上GCD是線程安全的所以在多線程中也能保證對象的唯一性。
另:在學習Objective-C編寫單例模式時看到網上好多人都借用蘋果官方的實現方式,但我自己始終沒搜到官方的實現Sample代碼,如果你知道麻煩把網址給我發下,謝謝哈~
新聞熱點
疑難解答