創(chuàng)建單例的2種方法

創(chuàng)建一個(gè)單例很多辦法。我先列舉一個(gè)蘋果官方文檔中的寫法。

[cpp]view plaincopy

staticAccountManager?*DefaultManager?=?nil;

+?(AccountManager?*)defaultManager?{

if(!DefaultManager)?DefaultManager?=?[[self?allocWithZone:NULL]?init];

returnDefaultManager;

}

當(dāng)然,在iOS4之后有了另外一種寫法:

[cpp]view plaincopy

+?(AccountManager?*)sharedManager

{

staticAccountManager?*sharedAccountManagerInstance?=?nil;

staticdispatch_once_t?predicate;

dispatch_once(&predicate,?^{

sharedAccountManagerInstance?=?[[self?alloc]?init];

});

returnsharedAccountManagerInstance;

}

該寫法來自objcolumnist,文中提到,該寫法具有以下幾個(gè)特性:

1. 線程安全。

2. 滿足靜態(tài)分析器的要求。

3. 兼容了ARC

然后我還有點(diǎn)好奇的是dispatch_once,這個(gè)函數(shù),沒見過啊。

于是就到官方的文檔里找找看,是怎么說的。

下面是官方文檔介紹:

dispatch_once

Executes a block object once and only once for the lifetime of an application.

void dispatch_once(

dispatch_once_t *predicate,

dispatch_block_t block);

Parameters

predicate

A pointer to adispatch_once_tstructure that is used to test whether the block has completed or not.

block

The block object to execute once.

Discussion

This function is useful for initialization of global data (singletons) in an application. Always call this function before using or testing any variables that are initialized by the block.

If called simultaneously from multiple threads, this function waits synchronously until the block has completed.

The predicate must point to a variable stored in global or static scope. The result of using a predicate with automatic or dynamic storage is undefined.

Availability

Available in iOS 4.0 and later.

Declared In

dispatch/once.h

我們看到,該方法的作用就是執(zhí)行且在整個(gè)程序的聲明周期中,僅執(zhí)行一次某一個(gè)block對(duì)象。簡(jiǎn)直就是為單例而生的嘛。而且,有些我們需要在程序開頭初始化的動(dòng)作,如果為了保證其,僅執(zhí)行一次,也可以放到這個(gè)dispatch_once來執(zhí)行。

然后我們看到它需要一個(gè)斷言來確定這個(gè)代碼塊是否執(zhí)行,這個(gè)斷言的指針要保存起來,相對(duì)于第一種方法而言,還需要多保存一個(gè)指針。

方法簡(jiǎn)介中就說的很清楚了:對(duì)于在應(yīng)用中創(chuàng)建一個(gè)初始化一個(gè)全局的數(shù)據(jù)對(duì)象(單例模式),這個(gè)函數(shù)很有用。

如果同時(shí)在多線程中調(diào)用它,這個(gè)函數(shù)將等待同步等待,直至該block調(diào)用結(jié)束。

這個(gè)斷言的指針必須要全局化的保存,或者放在靜態(tài)區(qū)內(nèi)。使用存放在自動(dòng)分配區(qū)域或者動(dòng)態(tài)區(qū)域的斷言,dispatch_once執(zhí)行的結(jié)果是不可預(yù)知的。

總結(jié):1.這個(gè)方法可以在創(chuàng)建單例或者某些初始化動(dòng)作時(shí)使用,以保證其唯一性。2.該方法是線程安全的,所以請(qǐng)放心大膽的在子線程中使用。(前提是你的dispatch_once_t *predicate對(duì)象必須是全局或者靜態(tài)對(duì)象。這一點(diǎn)很重要,如果不能保證這一點(diǎn),也就不能保證該方法只會(huì)被執(zhí)行一次。)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容