OC中的單例設計模式及單例的宏抽取

 

 

 

  1 // 在一個對象須要重複使用,而且很頻繁時,能夠對對象使用單例設計模式
  2 // 單例的設計其實就是多alloc內部的allocWithZone下手,重寫該方法
  3 
  4 #pragma Person.h文件
  5 
  6 #import <Foundation/Foundation.h>
  7 @interface Person : NSObject <NSCopying,NSMutableCopying>
  8 + (instancetype)sharePerson; // 給類提供一個建立單例對象的類工廠方法
  9 @end
 10 
 11 #pragma Person.m文件
 12 
 13 //
 14 //  Person.m
 15 //  單例設計
 16 //
 17 //  Created by 康生 邱 on 15/11/26.
 18 //  Copyright (c) 2015年 康生 邱. All rights reserved.
 19 //
 20 
 21 #import "Person.h"
 22 
 23 
 24 
 25 @implementation Person
 26 
 27 + (instancetype)sharePerson
 28 {
 29     Person *instance = [[self alloc] init]; // 單例設計能夠從alloc內的allocWithZone方法下手
 30     return instance;
 31 }
 32 static Person *_instance = nil;
 33 // 該方法決定了每次建立出來的是不是同一塊存儲空間的地址
 34 + (instancetype)allocWithZone:(struct _NSZone *)zone
 35 {
 36     // 若是_instance 等於nil,那麼就調用父類的alocWithZone來建立一個對象、初始化後賦值給它
 37     if (_instance == nil) {
 38         _instance = [[super allocWithZone:zone] init];
 39     }
 40     
 41     // 若是_instance 不等於nil,即已經指向了對象,那麼直接返回地址便可,這樣新建立的對象也指向同一個地址的對象
 42     return _instance;
 43 }
 44 
 45 - (id)copyWithZone:(NSZone *)zone
 46 {
 47     // copy是由對象調用的,在單例中對象已存在,就不須要建立對象了,直接返回對象指針便可
 48     return _instance;
 49 }
 50 
 51 - (id)mutableCopyWithZone:(NSZone *)zone
 52 {
 53     // mutableCopy和copy同樣,直接返回對象指針就能夠
 54     return _instance;
 55 }
 56 
 57 
 58 
 59 //  若是在MRC中,還須要重寫release、retain、retainCount
 60 - (oneway void)release
 61 {
 62     // 爲了保證單例對象在程序結束前不被釋放,\
 63     這裏什麼都不寫
 64 }
 65 - (instancetype)retain
 66 {
 67     // 直接返回單例對象地址
 68     return _instance;
 69 }
 70 - (NSUInteger)retainCount
 71 {
 72     // 能夠返回一個特殊的值,以提醒其餘程序員
 73 //    return MAXFLOAT;
 74     return UINT64_MAX;
 75 }
 76 
 77 @end
 78 
 79 
 80 #pragma - 對單例模式的宏抽取
 81 // 新建一個頭文件(Singleton.h)
 82 
 83 // 能夠使用interfaceSingleton替換掉Person類單例類工廠方法聲明
 84 #define interfaceSingleton(name) +(instancetype)share##name;
 85 
 86 // 若是當前工程在ARC下
 87 #if __has_feature(objc_arc)
 88 // ARC
 89 #define implementationSingleton(name) \
 90 + (instancetype)share##name \
 91 {\
 92     name *instance = [[self alloc] init];\
 93     return instance;\
 94 }\
 95 static  name *_instance = nil;\
 96 + (instancetype)allocWithZone:(struct _NSZone *)zone\
 97 {\
 98     if (_instance == nil) {\
 99         _instance = [[super allocWithZone:zone] init];\
100     }\
101     return _instance;\
102 }\
103 - (id)copyWithZone:(NSZone *)zone\
104 {\
105     return _instance;\
106 }\
107 - (id)mutableCopyWithZone:(NSZone *)zone\
108 {\
109     return _instance;\
110 }
111 #else
112 // MRC
113 #define implementationSingleton(name) \
114 + (instancetype)share##name \
115 {\
116 name *instance = [[self alloc] init];\
117 return instance;\
118 }\
119 static  name *_instance = nil;\
120 + (instancetype)allocWithZone:(struct _NSZone *)zone\
121 {\
122 if (_instance == nil) {\
123 _instance = [[super allocWithZone:zone] init];\
124 }\
125 return _instance;\
126 }\
127 - (id)copyWithZone:(NSZone *)zone\
128 {\
129 return _instance;\
130 }\
131 - (id)mutableCopyWithZone:(NSZone *)zone\
132 {\
133 return _instance;\
134 }\
135 - (oneway void)release\
136 {\
137 }\
138 - (instancetype)retain\
139 {\
140     return _instance;\
141 }\
142 - (NSUInteger)retainCount\
143 {\
144     return MAXFLOAT;\
145 }
146 // 結束條件編譯
147 #endif
148 
149 
150 經過將單例模式相關代碼抽取成一個頭文件,之後在類中只要導入待頭文件,並傳入類名便可
151 
152 #pragma - 單例宏抽取後的Person.h文件
153 
154 #import <Foundation/Foundation.h>
155 #import "Singleton.h"
156 @interface Person : NSObject <NSCopying,NSMutableCopying>
157 
158 interfaceSingleton(Person) // 宏定義,編譯時會把宏名替換成+ (instancetype)sharePerson;
159 // 參數的傳遞是告訴宏替換成方法聲明的時間share後面是什麼名稱
160 
161 @end
162 
163 
164 #pragma - 單例宏抽取後的Person.m文件
165 
166 #import "Person.h"
167 
168 @implementation Person
169 
170 // 經過宏定義,給實現文件中的代碼取別名,在實現中直接寫好宏名+ 當前的類名就好了
171 implementationSingleton(Person)
172 @end
View Code
相關文章
相關標籤/搜索