Objective-C(iOS)嚴格單例模式正確實現

注:本文全部權歸做者全部,轉載請註明出處  安全

  當但願在一個應用程序中某個類的對象只能存在一個的時候就能夠考慮用單例模式來實現,單例模式在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 Singleton
10 //單例類的靜態實例對象,因對象須要惟一性,故只能是static類型
11 static Singleton *defaultManager = nil;
12 
13 /**單例模式對外的惟一接口,用到的dispatch_once函數在一個應用程序內只會執行一次,且dispatch_once能確保線程安全
14 */
15 +(Singleton*)defaultManager
16 {
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 *)zone
30 {
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)init
42 {
43     self = [super init];
44     if(self)
45     {
46         self.name = @"Singleton";
47     }
48     return self;
49 }
50 
51 //覆蓋該方法主要確保當用戶經過copy方法產生對象時對象的惟一性
52 - (id)copy
53 {
54     return self;
55 }
56 
57 //覆蓋該方法主要確保當用戶經過mutableCopy方法產生對象時對象的惟一性
58 - (id)mutableCopy
59 {
60     return self;
61 }
62 //自定義描述信息,用於log詳細打印
63 - (NSString *)description
64 {
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:Singleton
13 2015-10-11 21:48:34.727 Singleton[1941:214584] allocSingleton:
14 memeory address:0x7fa6d1591530,property name:Singleton
15 2015-10-11 21:48:34.727 Singleton[1941:214584] copySingleton:
16 memeory address:0x7fa6d1591530,property name:Singleton
17 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代碼,若是你知道麻煩把網址給我發下,謝謝哈~測試

相關文章
相關標籤/搜索