最近幾年在開發(fā)項目時,使用的單例比較多,因為它確實方便了我們的開發(fā)。但是很多文章都提到的單例的缺點和弊端,這可能會讓一部分人放棄使用單例,我想說只要合理使用,它就能用!
一、單例的作用
方便我們在任何地方,訪問程序內(nèi)核心的值或者對象。
二、單例寫法
單例的寫法有很多,這里不舉例說明,只寫個人在用的。
// 寫法之一(蘋果推薦,主要用這個)
+ (instancetype)manager
{
static ConfigInfoManager *manager;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
manager = [[ConfigInfoManager alloc] init];
});
return manager;
}
三、單例的使用
所有的框架都有好有弊,不要因為在一些文章看到單例的弊端,類似違背了單一職責原則
、連接池溢出
、可擴展性比較差
、生命周期難管理
等等,就不去使用單例。類似Apple的UIApplication
、NSNotificationCenter
、NSFileManager
、NSUserDefaults
、NSURLCache
都是通過單例實現(xiàn)。
3.1、合理使用單例
1、合理的給單例劃分任務。類似apple的
UIApplication
、NSNotificationCenter
、NSFileManager
、NSUserDefaults
、NSURLCache
,一個類只負責一個功能,需要實現(xiàn)多個功能,那就創(chuàng)建多個類。濫用單例、沒有合理的給單例劃分任務
,才會導致違背了單一職責原則。2、關于單例的生命周期。單例對象一旦創(chuàng)建,對象指針是保存在靜態(tài)區(qū)的,單例對象在堆中分配的內(nèi)存空間只有在程序終止后才會釋放。如果需要主動釋放,那我覺得這種情況沒必要使用單例。還有很多解決的方法類似
category
和類方法
等。3、作用域。這里就是要確定是否真的需要使用單例,明確實現(xiàn)功能的使用范圍,如果是需要在程序中的任何地方訪問,那就用單例。如果確定只在幾個頁面中使用,那就尋找別的替代方案。
3.2、個人使用單例的一些場景
1、獲取程序內(nèi)長鏈接的狀態(tài)。類似
mqtt
、websocket
,隨時獲取消息數(shù)更新顯示等2、獲取字典表配置信息。假如程序內(nèi)存在很多內(nèi)容,都是根據(jù)同一個接口(即字典表)返回顯示,因為這些配置信息會發(fā)生變化,所以不能在程序內(nèi)配置死,需要從接口獲取并顯示。為了避免在每一個使用到的地方都去調(diào)用接口,這一類接口我都會使用單例處理,在應用打開期間只獲取一次,有時是在打開app后獲取,有些是在首次使用時獲取,根據(jù)使用情況做處理。
3、一些第三方庫的使用。類似網(wǎng)易云信的音視頻通話,因為通話是隨時發(fā)生的,不確定在哪個頁面,為了內(nèi)容管理和方便開發(fā),我會選擇使用單例去解決。
4、保存用戶信息和登錄狀態(tài)。這里需要注意,用戶信息修改時要及時更新,用戶退出后也要清除登錄狀態(tài)和用戶信息。
5、保存頁面刷新狀態(tài)。個人的做法是,單例內(nèi)創(chuàng)建了一個字段,保存以頁面的名稱為key,保存頁面是否需要刷新的狀態(tài)。類似詳情修改了需要刷新首頁,在
viewWillAppear
內(nèi)每次刷新,顯得有點資源浪費;使用通知、代理和block增加了不少代碼開發(fā)量;并且每個頁面都實現(xiàn)類似的功能,重復工作較多。