iOS單例模式
什么是單例模式枕稀?
單例模式:保證一個類僅有一個實例仍劈,并提供一個唯一的全局訪問點哈雏。
蘋果大量使用了此模式卓起。例如:[NSUserDefaults standardUserDefaults],[UIApplication sharedApplication],[UIScreen mainScreen],[NSFileManager defaultManager]载荔,所有的這些方法都返回一個單例對象盾饮。
單例模式的優(yōu)缺點
優(yōu)點:
將一些初始化比較耗費資源的類寫成單例,避免重復(fù)的初始化耗費資源懒熙∏鹚穑或者一些創(chuàng)建和銷毀比較頻繁的類,用單例模式可以提高性能煌珊。
單例的唯一性和全局性可以很方便的用來傳值号俐。
缺點:
單例創(chuàng)建之后,對象保存在靜態(tài)區(qū)定庵,在程序結(jié)束之后才會釋放吏饿,過多的單例會增加常駐內(nèi)存消耗。
單例的職責(zé)過重蔬浙,在一定程度上違背了“單一職責(zé)原則”猪落。
單例沒有抽象層,因此單例類的擴展有很大困難畴博。
由于程序的任一模塊都可以訪問單例笨忌,如果某個與單例進行交互的代碼出現(xiàn)了問題,很容易影響其他使用到單例的地方俱病。
單例的寫法
創(chuàng)建一個單例類官疲,在.h文件聲明單例的初始化方法袱结。
+ (instancetype)shareSingleton;
在.m文件里實現(xiàn),使用static修飾途凫,保證實例全局存在垢夹。使用GCD的dispatch_once方法來保證初始化代碼只執(zhí)行一次。
@implementation LDSingletonstatic LDSingleton *instance;+ (instancetype)shareSingleton {? ? static dispatch_once_t onceToken;? ? dispatch_once(&onceToken, ^{? ? ? ? instance = [[self alloc]init];? ? });? ? return instance;}@end
為了避免在外部使用其他初始化方法創(chuàng)建單例對象维费,導(dǎo)致單例類有多個實例對象果元。可以重寫allocWithZone:犀盟、copyWithZone:和mutableCopyWithZone:方法而晒,并返回唯一的單例對象。
禁用其他獲取實例方法
也可以禁用外部調(diào)用其他初始化方法阅畴,來保證單例的唯一性倡怎。在.h文件聲明:
- (instancetype)init NS_UNAVAILABLE;+ (instancetype)new NS_UNAVAILABLE;- (id)copy NS_UNAVAILABLE;- (id)mutableCopy NS_UNAVAILABLE;
這些方法不用實現(xiàn)。由于使用NS_UNAVAILABLE宏贱枣,在外部調(diào)用init等方法時編譯器會報錯诈胜。
一個便捷的可繼承單例方法
這有個demo。
導(dǎo)入文件:
只要引入頭文件冯事,遵守協(xié)議就可以成為一個單例類。
#import "NSObject+LDOptionalSingleton.h"@interface Person : NSObject<LDOptionalSingleton>@end
獲取單例對象:
[Person LD_sharedSingleton];
原理是使用runtime關(guān)聯(lián)對象方法血公,加上分類和協(xié)議昵仅。單例可以繼承,并且父類和子類擁有各自的單例對象累魔。