單例模式

@synchronized

  1. 定義一個靜態(tài)的全局的變量
    static Settings *sharedSettings = nil;

  2. 創(chuàng)建一個類方法,用來返回該類實例
    synchronized 這個主要是考慮多線程的程序,這個指令可以將{ } 內的代碼限制在一個線程執(zhí)行,如果某個線程沒有執(zhí)行完盐类,其他的線程如果需要執(zhí)行就得等著赋铝。

 + (Settings *)sharedInstance {
@synchronized(self){
if(sharedSettings  ==  nil){
            sharedSettings = [[self alloc] init];
          //做一些初始化操作
        }
    }
return  sharedSettings;
}
  1. 重寫allocWithZone方法,用來保證其他人直接使用alloc和init試圖獲得一個新實力的時候不產生一個新實例迁杨,
 + (id)allocWithZone:(NSZone *)zone {
@synchronized(self) {
        if (sharedSettings == nil) {
            sharedSettings = [super allocWithZone:zone];
        }
    }
    return sharedSettings;
}

dispatch_once
有些變量只需要初始化一次(如從文件中讀取配置參數诗眨,讀取設備型號等等)唉匾,可以使用dispatch_once來進行讀取優(yōu)化,保證只調用API一次匠楚,以后就只要直接訪問變量即可
void dispatch_once( dispatch_once_t *predicate, dispatch_block_t block);
dispatch_once不僅意味著代碼僅會被運行一次巍膘,而且還是線程安全的,這就意味著你不需要使用諸如
@synchronized之類的來防止使用多個線程或者隊列時不同步的問題芋簿。

//范例如下:
static BOOL isTestMode;

+ (BOOL)isTestMode {

  static dispatch_once_t onceToken;
  dispatch_once(&onceToken, ^{
  NSNumber* obj = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFResourceTest"];
  isTestMode = [obj boolValue];
    });

  return isTestMode;
}

實際要如何使用這些呢?
好吧峡懈,假設有一個AccountManager類,你想在整個應用中訪問該類的共享實例与斤。你可以按如下代碼簡單實現一個類方法:

+ (AccountManager *)sharedManager {

  static AccountManager *sharedAccountManagerInstance = nil;
  static dispatch_once_t predicate;
  dispatch_once(&predicate, ^{
        sharedAccountManagerInstance = [[self alloc] init];
    });
  return sharedAccountManagerInstance;
}

這就意味著你任何時候訪問共享實例逮诲,需要做的僅是:

AccountManager *accountManager = [AccountManager sharedManager];
該方法有很多優(yōu)勢
a. 線程安全
b. 很好滿足靜態(tài)分析器要求
c. 和自動引用計數(ARC)兼容
d. 僅需要少量代碼

就這些,你現在在應用中就有一個共享的實例幽告,該實例只會被創(chuàng)建一次。

該方法有很多優(yōu)勢
a. 線程安全
b. 很好滿足靜態(tài)分析器要求
c. 和自動引用計數(ARC)兼容
d. 僅需要少量代碼

該方法的劣勢就是它仍然運行創(chuàng)建一個非共享的實例:我們通常在OC中實現一個單例方法都是這樣:

static HLTestObject *instance = nil;
+ (instancetype)sharedInstance {

    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [[[self class] alloc] init];
    });
    return instance;
}

可是這樣就可以了么裆甩?我做了如下測試:

HLTestObject *objct1 = [HLTestObject sharedInstance];
NSLog(@"%@",objct1);
HLTestObject *objc2 = [[HLTestObject alloc] init];
NSLog(@"%@",objc2);
HLTestObject *objc3 = [HLTestObject new];
NSLog(@"%@",objc3);

看到這個測試冗锁,你想到打印結果了么?結果是這樣的:

2016-05-23 12:52:57.095 PractiseProject[3579:81998] <hltestobject: 0x7fcf39515510>
2016-05-23 12:52:57.095 PractiseProject[3579:81998] <hltestobject: 0x7fcf395c4b70>
2016-05-23 12:52:57.095 PractiseProject[3579:81998] <hltestobject: 0x7fcf395c6890></hltestobject: 0x7fcf395c6890></hltestobject: 0x7fcf395c4b70></hltestobject: 0x7fcf39515510>

很明顯嗤栓,通過三種方式創(chuàng)建出來的是不同的實例對象冻河,這就違背了單例類有且僅有一個實例的定義。

為了防止別人不小心利用alloc/init方式創(chuàng)建示例茉帅,也為了防止別人故意為之叨叙,我們要保證不管用什么方式創(chuàng)建都只能是同一個實例對象,這就得重寫另一個方法堪澎,實現如下:

static TYGAreaPickerView *sharedObject = nil;
+ (TYGPlaceholderHelper *)sharedInstance {

    static dispatch_once_t _singletonPredicate;
    dispatch_once(&_singletonPredicate, ^{
        sharedObject = [[super allocWithZone:nil] init];
    });
    return sharedObject;
}

+ (id)allocWithZone:(NSZone *)zone {
    return [self sharedInstance];
}
static HLTestObject *instance = nil;
+ (instancetype)sharedInstance {

    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [[[self class] alloc] init];
        instance.height = 10;
        instance.object = [[NSObject alloc] init];
        instance.arrayM = [[NSMutableArray alloc] init];
    });
    return instance;
}

+ (instancetype)allocWithZone:(struct _NSZone *)zone {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [super allocWithZone:zone];
    });
    return instance;
}
static HLTestObject *instance = nil;
+ (instancetype)sharedInstance {
    return [[self alloc] init];
}
- (instancetype)init {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [super init];
        instance.height = 10;
        instance.object = [[NSObject alloc] init];
        instance.arrayM = [[NSMutableArray alloc] init];
    });
    return instance;
}
+ (instancetype)allocWithZone:(struct _NSZone *)zone {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [super allocWithZone:zone];
    });
    return instance;
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末擂错,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子樱蛤,更是在濱河造成了極大的恐慌钮呀,老刑警劉巖剑鞍,帶你破解...
    沈念sama閱讀 219,188評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現場離奇詭異爽醋,居然都是意外死亡蚁署,警方通過查閱死者的電腦和手機,發(fā)現死者居然都...
    沈念sama閱讀 93,464評論 3 395
  • 文/潘曉璐 我一進店門蚂四,熙熙樓的掌柜王于貴愁眉苦臉地迎上來光戈,“玉大人,你說我怎么就攤上這事遂赠【米保” “怎么了?”我有些...
    開封第一講書人閱讀 165,562評論 0 356
  • 文/不壞的土叔 我叫張陵解愤,是天一觀的道長镇饺。 經常有香客問我,道長送讲,這世上最難降的妖魔是什么奸笤? 我笑而不...
    開封第一講書人閱讀 58,893評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮哼鬓,結果婚禮上监右,老公的妹妹穿的比我還像新娘。我一直安慰自己异希,他們只是感情好健盒,可當我...
    茶點故事閱讀 67,917評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著称簿,像睡著了一般扣癣。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上憨降,一...
    開封第一講書人閱讀 51,708評論 1 305
  • 那天父虑,我揣著相機與錄音,去河邊找鬼授药。 笑死士嚎,一個胖子當著我的面吹牛,可吹牛的內容都是我干的悔叽。 我是一名探鬼主播莱衩,決...
    沈念sama閱讀 40,430評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼娇澎!你這毒婦竟也來了笨蚁?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,342評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎赚窃,沒想到半個月后册招,有當地人在樹林里發(fā)現了一具尸體,經...
    沈念sama閱讀 45,801評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡勒极,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,976評論 3 337
  • 正文 我和宋清朗相戀三年是掰,在試婚紗的時候發(fā)現自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片辱匿。...
    茶點故事閱讀 40,115評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡键痛,死狀恐怖,靈堂內的尸體忽然破棺而出匾七,到底是詐尸還是另有隱情絮短,我是刑警寧澤,帶...
    沈念sama閱讀 35,804評論 5 346
  • 正文 年R本政府宣布昨忆,位于F島的核電站丁频,受9級特大地震影響,放射性物質發(fā)生泄漏邑贴。R本人自食惡果不足惜席里,卻給世界環(huán)境...
    茶點故事閱讀 41,458評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望拢驾。 院中可真熱鬧奖磁,春花似錦、人聲如沸繁疤。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,008評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽稠腊。三九已至躁染,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間架忌,已是汗流浹背褐啡。 一陣腳步聲響...
    開封第一講書人閱讀 33,135評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留鳖昌,地道東北人。 一個月前我還...
    沈念sama閱讀 48,365評論 3 373
  • 正文 我出身青樓低飒,卻偏偏與公主長得像许昨,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子褥赊,可洞房花燭夜當晚...
    茶點故事閱讀 45,055評論 2 355

推薦閱讀更多精彩內容

  • 單例模式 什么是單例模式糕档? 單例模式想一個大獨裁者,他規(guī)定在他的國度里面,所有數據的訪問和請求都得經過他速那,甚至你要...
    GitHubPorter閱讀 1,161評論 0 4
  • 線程間的通信 從子線程回到主線程 延時執(zhí)行 iOS常見的延時執(zhí)行有兩種方式p 調用NSObject的方法 p 使用...
    一抹月光3053閱讀 758評論 1 12
  • @WilliamAlex大叔 前言 目前流行的社交APP中都離不開單例的使用,我們來舉個例子哈,比如現在流行的"糗...
    Alexander閱讀 1,920評論 6 28
  • 一. ARC環(huán)境下的單例模式 單例模式的基本概念單例, 顧名思義, 即在整個程序中, 某一個類只有唯一一個實例, ...
    面糊閱讀 757評論 0 50
  • 有些人一開口俐银,你就知道這人厲害。曾經一度巨羨慕這樣的人端仰。 思路清晰捶惜,分工明確,直達重點..... 元認知荔烧,一種反思...
    Alexis_趙楠閱讀 186評論 4 3