重點 (一) : 單例模式
單例模式的作用
可以保證在程式執行過程,一個類只有一個例項,而且該例項易於供外界訪問
從而方便地控制了例項個數,並節約系統資源
單例模式的使用場合
在整個應用程式中,共享一份資源(這份資源只需要建立初始化1次)
單例模式在ARC\MRC環境下的寫法有所不同,需要編寫2套不同的程式碼
可以用巨集判斷是否為ARC環境
if __has_feature(objc_arc)
// ARC
else
// MRC
endif
單例模式 - ARC
ARC中,單例模式的實現
在.m中保留一個全域性的static的例項
static id _instance;
重寫allocWithZone:方法,在這裡建立唯一的例項(注意執行緒安全)
(id)allocWithZone:(struct
_NSZone *)zone {
if (_instance == nil) { //
防止頻繁加鎖
@synchronized(self) {
if
(_instance== nil) { //
防止建立多次
_instance = [super allocWithZone:zone];
}
}
}
return _instance;
}
提供1個類方法讓外界訪問唯一的例項
(instancetype)sharedMusicTool {
if (_instance == nil) { //
防止頻繁加鎖
@synchronized(self) {
if
(_instance== nil) { //
防止建立多次
_instance
= [[self alloc]
init];
}
}
}
return _instance;
}
實現copyWithZone:方法
(id)copyWithZone:(struct
_NSZone *)zone {
return _instance;
}
單例模式 – 非ARC
非ARC中(MRC),單例模式的實現(比ARC多了幾個步驟)
實現記憶體管理方法
(id)retain { return
self; }
(NSUInteger)retainCount {return 1; }
(oneway void)release {}
- (id)autorelease { return
self; }
************************筆記****************************
1.單例模式
- 1.1 概念相關
(1)單例模式
在程式執行過程,一個類只有一個例項
(2)使用場合
在整個應用程式中,共享一份資源(這份資源只需要建立初始化1次)
- 1.2
ARC實現單例
(1)步驟
01 在類的內部提供一個static修飾的全域性變數
02 提供一個類方法,方便外界訪問
03 重寫+allocWithZone方法,保證永遠都只為單例物件分配一次記憶體空間
04 嚴謹起見,重寫-copyWithZone方法和-MutableCopyWithZone方法
(2)相關程式碼
提供一個static修飾的全域性變數,強引用著已經例項化的單例物件例項
static XMGTools *_instance;
類方法,返回一個單例物件
+(instancetype)shareTools
{
注意:這裡建議使用self,而不是直接使用類名Tools(考慮繼承)
return [[self
alloc]init];
}
保證永遠只分配一次儲存空間
+(instancetype)allocWithZone:(struct _NSZone *)zone
{
使用GCD中的一次性程式碼
static
dispatch_once_t onceToken;
dispatch_once(&onceToken,
^{
_instance
= [super allocWithZone:zone];
});
使用加鎖的方式,保證只分配一次儲存空間
@synchronized(self) {
if (_instance ==nil) {
_instance = [super
allocWithZone:zone];
}
}
return _instance;
}
mutableCopy 建立一個新的可變物件,並初始化為原物件的值,新物件的引用計數為1;
copy 返回一個不可變物件。分兩種情況:(1)若原物件是不可變物件,那麼返回原物件,並將其引用計數加1;(2)若原物件是可變物件,那麼建立一個新的不可變物件,並初始化為原物件的值,新物件的引用計數為1。
讓程式碼更加的嚴謹
-(nonnull id)copyWithZone:(nullable
NSZone *)zone
{
return [[self class] allocWithZone:zone];
return _instance;
}
-(nonnull id)mutableCopyWithZone:(nullable NSZone *)zone
{
return _instance;
}
- 1.3
MRC實現單例
(1)實現步驟
01 在類的內部提供一個static修飾的全域性變數
02 提供一個類方法,方便外界訪問
03 重寫+allocWithZone方法,保證永遠都只為單例物件分配一次記憶體空間
04 嚴謹起見,重寫-copyWithZone方法和-MutableCopyWithZone方法
05 重寫release方法
06 重寫retain方法
07 建議在retainCount方法中返回一個最大值
(2)配置MRC環境知識
01 注意ARC不是垃圾回收機制,是編譯器特性
02 配置MRC環境:build
setting ->搜尋automatic ref->修改為NO
(3)相關程式碼
提供一個static修飾的全域性變數,強引用著已經例項化的單例物件例項
static XMGTools *_instance;
類方法,返回一個單例物件
+(instancetype)shareTools
{
注意:這裡建議使用self,而不是直接使用類名Tools(考慮繼承)
return [[self
alloc]init];
}
保證永遠只分配一次儲存空間
+(instancetype)allocWithZone:(struct _NSZone *)zone
{
使用GCD中的一次性程式碼
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instance = [super allocWithZone:zone];
});
使用加鎖的方式,保證只分配一次儲存空間
@synchronized(self) {
if (_instance ==nil) {
_instance = [super
allocWithZone:zone];
}
}
return _instance;
}
讓程式碼更加的嚴謹
-(nonnull id)copyWithZone:(nullable
NSZone *)zone
{
return
[[self class] allocWithZone:zone];
return _instance;
}
-(nonnull id)mutableCopyWithZone:(nullable NSZone *)zone
{
return _instance;
}
在MRC環境下,如果使用者retain了一次,那麼直接返回instance變數,不對引用計數器+1
如果使用者release了一次,那麼什麼都不做,因為單例模式在整個程式執行過程中都擁有且只有一份,程式退出之後被釋放,所以不需要對引用計數器操作
-(oneway void)release
{
}
-(instancetype)retain
{
return _instance;
}
慣用法,有經驗的程式設計師通過列印retainCount這個值可以猜到這是一個單例
-(NSUInteger)retainCount
{
return MAXFLOAT;
}
- 1.4 通用版本
(1)有意思的對話
01 問:寫一份單例程式碼在ARC和MRC環境下都適用?
答:可以使用條件編譯來判斷當前專案環境是ARC還是MRC
02 問:條件編譯的程式碼呢,麼麼噠?
答:條件編譯
if
__has_feature(objc_arc)
如果是ARC,那麼就執行這裡的程式碼1
else
如果不是ARC,那麼就執行代理的程式碼2
endif
03 問:在專案裡面往往需要實現很多的單例,比如下載、網路請求、音樂播放等等,弱弱的問一句單例可以用繼承嗎?
答:單例是不可以用繼承的,如果想寫一次四處使用,那麼推薦親使用帶引數的巨集定義啦!
04 問:巨集定義怎麼弄?
答:這個嘛~~回頭看一眼我的程式碼咯,親。
(2)使用帶引數的巨集完成通用版單例模式程式碼
01 注意條件編譯的程式碼不能包含在巨集定義裡面
02 巨集定義的程式碼只需要寫一次就好,之後直接拖到專案中用就OK
相關文章
- 重學設計模式-單例模式設計模式單例
- Java單例模式:缺點和優點Java單例模式
- 設計模式(一)_單例模式設計模式單例
- 設計模式一(單例模式)設計模式單例
- 設計模式學習(一)單例模式補充——單例模式析構設計模式單例
- javascript設計模式一: 單例模式JavaScript設計模式單例
- 設計模式(一)之單例模式設計模式單例
- 單例模式(下)---聊一聊單例模式的幾種寫法單例模式
- 單例模式(下) - 聊一聊單例模式的幾種寫法單例模式
- 單例模式(下) – 聊一聊單例模式的幾種寫法單例模式
- java設計模式其一 單例模式Java設計模式單例
- 單例模式單例模式
- Scala 與設計模式(一):Singleton 單例模式設計模式單例
- PHP設計模式(一)—單例模式(Singleton Pattern)PHP設計模式單例
- 設計模式(一)建立型之單例模式設計模式單例
- 建立型模式之單例模式與工廠模式(一)模式單例
- 設計模式(三)----建立型模式之單例模式(一)設計模式單例
- 每天一個設計模式之單例模式設計模式單例
- Go 實現常用設計模式(一)單例模式Go設計模式單例
- 創造模式 單例模式模式單例
- 建立型模式:單例模式模式單例
- 設計模式(單例模式)設計模式單例
- [設計模式] 單例模式設計模式單例
- 設計模式-單例模式設計模式單例
- 設計模式 —— 單例模式設計模式單例
- 設計模式 單例模式設計模式單例
- 設計模式——單例模式設計模式單例
- 單例模式解析單例模式
- python 單例模式Python單例模式
- java 單例模式Java單例模式
- 單例模式(Singleton)單例模式
- php單例模式PHP單例模式
- 單例模式(3)單例模式
- Java單例模式Java單例模式
- 單例模式 singleton單例模式
- 單例模式(SingletonPattern)單例模式
- python單例模式Python單例模式
- 您的單例模式,真的單例嗎?單例模式
- 美團一面:會單例模式嗎,寫個單例看看?(8大單例模式實現方式總結)單例模式