就是保證某個類建立出來的物件從始到終只有乙個的一種方案
首先將我們的環境設定為非arc環境,即mrc,如圖
在mrc模式下,我們得自己手動釋放資源,所以得重寫一些與資源建立與釋放相關的方法,以保證單例物件的唯一。新建乙個繼承於nsobject的類 lxffiletool,我直接上**,並寫上注釋 lxffiletool.h
@inte***ce
lxffiletool : nsobject
+ (instancetype)sharedfiletool;
@end
複製**
lxffiletool.m
#import "lxffiletool.h"
@implementation
lxffiletool
static lxffiletool *_filetools = nil;
/** * alloc方法內部會呼叫allocwithzone:
*/+ (instancetype)allocwithzone:(struct _nszone *)zone );
}return _filetools;
}- (oneway
void)release
// 重寫retain方法
- (instancetype)retain
// 重寫retaincount鎖定引用計數
- (nsuinteger)retaincount
// 重寫init方法,防止單例所擁有的屬性值被重置
// 讓初始化的方法只能執行一次,自然屬性值就沒有機會被重置
- (instancetype)init );
return _filetools;
}// 仿造系統的單例建立方式,提供類方法
+ (instancetype)sharedfiletool
@end
複製**
mrc下就是這樣,我們的目的就是只能建立和初始化一次物件,不給機會釋放,也不給機會重新初始化,從而保證了該物件的唯一。那現在來看看arc下是如何實現單例的吧。其實arc下與mrc的區別就是arc下我們不用自己再手動去釋放資源了,從而使**上大同小異,如下所示。
#import "lxffiletool.h"
@implementation
lxffiletool
static lxffiletool *_filetools = nil;
+ (instancetype)allocwithzone:(struct _nszone *)zone );
}return _filetools;
}- (instancetype)init );
return _filetools;
}+ (instancetype)sharedfiletool
複製**
現在我們已經知道了arc與mrc下分別是如何建立單例的了,但是如果我們乙個專案裡需要多個單例,那我們只能把**複製貼上再改改就完事嗎?這未免也太麻煩了吧。那我們能不能做到快速且方便的建立單例物件呢?可以的,利用巨集首先先說下一些關於巨集的知識吧
那現在來討論下一些疑惑吧,你說巨集只能單行,可是建立單例的**可是有很多行呀!還有我們如何做到自定義類方法名(就是 shared*** )?好,我們來介紹下巨集下的兩個特殊符號作用\
用來轉譯換行符,即遮蔽換行符
##將兩個相鄰的標記(token)連線為乙個單獨的標記
簡單來說,\用於取消換行,##用來連線,而我們就用##來實現自定義類方法名建立乙個標頭檔案singleton.h用來存放巨集定義 先來看看定義.h中 shared*** 是如何通過巨集來定義的
// .**件的實現
#define singletonh(methodname) + (instancetype)shared##methodname;
複製**
現在回到lxffiletool.h中,直接一行定義sharedfiletool這個類方法
#import "singleton.h"
@inte***ce
lxffiletool : nsobject
singletonh(filetool)
@end
複製**
我們只需要將方法名filetool傳入singletonh()中就可以拼接為sharedfiletool
那現在再來看看定義.m中建立單例的方式,以arc為例
#define singletonm(methodname) \
static
id _instance = nil; \
+ (instancetype)allocwithzone:(struct _nszone *)zaone ); \
} \return _instance; \
} \\
- (instancetype)init ); \
return _instance; \
} \\
+ (instancetype)shared##methodname
複製**
在每乙個行後面加上(反斜槓)取消換行,使用##來拼接傳入的方法名,但還有一點需要注意:最後一行不能加反斜槓回到lxffiletool.m中,一行實現建立單例
#import "lxffiletool.h"
@implementation
lxffiletool
singletonm(filetool)
@end
複製**
#if __has_feature(objc_arc) // arc
// 寫上arc下的定義**
#else // 非arc
// 寫上mrc下的定義**
#endif
複製**
好了,現在用起來是不是方便多了?我們只要建立乙個類,然後在.**件中寫singletonh(***),再在.m檔案中寫singletonm(***)就可以實現單例了~順便提下如何在mrc下指定某個類檔案使用的環境為arc
如圖,可以在 build phases -> compile sources 中雙擊某個需要arc環境的類檔案,然後寫上
-fobjc-arc
複製**
如果是指定mrc,則寫上
-fno-objc-arc
複製**
最後,附上demo: lxfsingleton iOS ARC與MRC混編的一些解決方法
1.arc mrc 混合開發 在專案開發中,遇到使用mrc開發的第三方庫怎麼辦?例如 asi 1 嘗試使用xcode的轉換工具 失敗率比較高 2 在編譯選項中,為mrc的程式新增 fno objc arc標記,表明在編譯時,該檔案使用mrc編譯 備註 1 演示中使用的regexkitlite還需要匯...
ARC和MRC 相容的單例模式
一 arc下的單例實現 說明 在使用者例項化的方法控制單次執行,同時開放單例的初始化方法。instancetype init return self static id instance instancetype allocwithzone struct nszone zone return ins...
單例的設計與作用
單例模式 是指乙個類如果設定為單例模式,那麼這個類只能建立乙個物件。而單例模式多數用於初始化時使用。單例的兩大特性 1 可以保證物件的唯一性。2 可以保證執行緒的安全性。下面建立乙個單例模式的例子 instancetype shareinstance return dbengine 需要注意的是 這...