iOS ARC與MRC的單例設計模式

2021-09-11 11:07:35 字數 3484 閱讀 2338

就是保證某個類建立出來的物件從始到終只有乙個的一種方案

首先將我們的環境設定為非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 需要注意的是 這...