單例模式
單例模式:單例模式確保某一個(gè)類只有一個(gè)實(shí)例靠欢,而且自行實(shí)例化并向整個(gè)系統(tǒng)提供這個(gè)實(shí)例倘屹,這個(gè)類稱為單例類记劝,它提供全局訪問的方法。
要點(diǎn):1.某個(gè)類只能有一個(gè)實(shí)例 2. 它必須自行創(chuàng)建這個(gè)單例吕粹。 3.它必須自行向整個(gè)系統(tǒng)提供這個(gè)實(shí)例种柑。單例模式是一種對象創(chuàng)建行模式。
實(shí)現(xiàn)過程: 1.單例類的構(gòu)造函數(shù)為私有 2. 提供一個(gè)自身的靜態(tài)私有成員變量匹耕。 3.提供一個(gè)公有的靜態(tài)工廠方法聚请。
注解:該模式中包含一個(gè)靜態(tài)私有成員變量與靜態(tài)公有的工廠方法,該工廠方法負(fù)責(zé)檢驗(yàn)實(shí)例的存在性并實(shí)例化自己稳其,然后存儲在靜態(tài)成員變量中驶赏,以確保只有一個(gè)實(shí)例被創(chuàng)建。
總結(jié)
* 單例模式確保某一個(gè)類只有一個(gè)實(shí)例既鞠,而且自行實(shí)例化并向整個(gè)系統(tǒng)提供這個(gè)實(shí)例煤傍,這個(gè)類稱為單例類,它提供全局訪問的方法嘱蛋。單例模式的要點(diǎn)有三個(gè):一是某個(gè)類只能有一個(gè)實(shí)例蚯姆;二是它必須自行創(chuàng)建這個(gè)實(shí)例;三是它必須自行向整個(gè)系統(tǒng)提供這個(gè)實(shí)例洒敏。單例模式是一種對象創(chuàng)建型模式龄恋。
* 單例模式只包含一個(gè)單例角色:在單例類的內(nèi)部實(shí)現(xiàn)只生成一個(gè)實(shí)例,同時(shí)它提供一個(gè)靜態(tài)的工廠方法凶伙,讓客戶可以使用它的唯一實(shí)例郭毕;為了防止在外部對其實(shí)例化,將其構(gòu)造函數(shù)設(shè)計(jì)為私有函荣。
* 單例模式的目的是保證一個(gè)類僅有一個(gè)實(shí)例显押,并提供一個(gè)訪問它的全局訪問點(diǎn)。單例類擁有一個(gè)私有構(gòu)造函數(shù)傻挂,確保用戶無法通過new關(guān)鍵字直接實(shí)例化它乘碑。除此之外,該模式中包含一個(gè)靜態(tài)私有成員變量與靜態(tài)公有的工廠方法踊谋。該工廠方法負(fù)責(zé)檢驗(yàn)實(shí)例的存在性并實(shí)例化自己蝉仇,然后存儲在靜態(tài)成員變量中旋讹,以確保只有一個(gè)實(shí)例被創(chuàng)建殖蚕。
* 單例模式的主要優(yōu)點(diǎn)在于提供了對唯一實(shí)例的受控訪問并可以節(jié)約系統(tǒng)資源轿衔;其主要缺點(diǎn)在于因?yàn)槿鄙俪橄髮佣y以擴(kuò)展,且單例類職責(zé)過重睦疫。
* 單例模式適用情況包括:系統(tǒng)只需要一個(gè)實(shí)例對象害驹;客戶調(diào)用類的單個(gè)實(shí)例只允許使用一個(gè)公共訪問點(diǎn)。
- 單例類的生命周期
位置 | 存放的變量 |
---|---|
棧 | 臨時(shí)變量(由編譯器管理自動創(chuàng)建/分配/釋放的蛤育,棧中的內(nèi)存被調(diào)用時(shí)處于存儲空間中宛官,調(diào)用完畢后由系統(tǒng)系統(tǒng)自動釋放內(nèi)存) |
堆 | 通過alloc、calloc瓦糕、malloc或new 申請內(nèi)存底洗,由開發(fā)者手動在調(diào)用之后通過free或delete釋放內(nèi)存。動態(tài)生存的生存期可以由我們決定咕娄,如果我們不釋放內(nèi)存亥揖,程序?qū)⒃谧詈蟛裴尫诺魟討B(tài)內(nèi)存,在ARC模式下圣勒,系統(tǒng)自動管理费变。 |
全局區(qū) | 靜態(tài)變量(編譯時(shí)分配,APP結(jié)束時(shí)由系統(tǒng)釋放) |
常量區(qū) | 常量(編譯時(shí)分配圣贸,APP結(jié)束時(shí)由系統(tǒng)釋放) |
代碼區(qū) | 存放代碼 |
在程序中挚歧,一個(gè)單例類在程序中只能初始化一次,為了保證在使用中始終都是存在的吁峻,所以單例是在存儲器的全局區(qū)域滑负,在編譯時(shí)分配內(nèi)存,只要程序還在運(yùn)行就會一直占用內(nèi)存用含,在APP結(jié)束后由系統(tǒng)釋放這部分內(nèi)存內(nèi)存橙困。
ps: load方法是在整個(gè)文件被加載到運(yùn)行時(shí),在main函數(shù)調(diào)用之前調(diào)用耕餐;
initialize方法是在該類第一次調(diào)用該類時(shí)調(diào)用凡傅;
+(instancetype) sharedInstance{
static Singleton * _instance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instance= [[self alloc] init];
});
return _instance;
}