天天看點

Singleton 單例模式

singleton 單例模式,又叫單子模式,是一種常見的軟體設計模式。這種模式的特點就是應用了 singleton 單例模式的類必須保證始終隻有一個執行個體(對象)存在。許多時候系統中需要某個類隻能同時存在一個對象,而且可以全局調用。

單例模式的思路是一個類能傳回對象一個執行個體(永遠是同一個)和一個獲得該執行個體的方法(必須是靜态方法,通常使用 getinstance這個名稱);當我們調用這個方法時,如果類持有的執行個體不為空,就傳回這個執行個體;如果類保持的執行個體為空,就建立該類的執行個體,并将執行個體賦予該類保持的執行個體,進而限制使用者隻有通過該類提供的靜态方法來得到該類唯一的執行個體。

單例模式在多線程場合下必須小心使用。當唯一的執行個體未建立時,如果有兩個線程同時調用建立方法,那麼他們同時沒有檢測到唯一的執行個體存在,進而同時各自建立了一個執行個體,這樣就有兩個執行個體被建立出來,進而違反了單例模式中執行個體唯一的原則。解決這個問題的辦法是為标記類是否已經執行個體化的變量提供一個互斥鎖(雖然這樣會降低效率)。

下面用一個例子來說明問題:

一:為你的單例類聲明一個靜态的執行個體,并且初始化它的值為nil。

二:在擷取執行個體的方法中(比如下例中的 getinstance),隻有在靜态執行個體為nil的時候,産生一個你的類的執行個體,這個執行個體通常被稱為共享的執行個體。

三:重寫allocwithzone 方法,用于确定:不能夠使用其他的方法來建立我們不得執行個體,限制使用者隻能通過擷取執行個體的方法得到這個類的執行個體。是以,我們在allocwithzone方法中直接傳回共享的類執行個體。

四:實作基本的協定方法 copywithzone、release、retain、retaincount 和 autorelease,用于保證單例具有一個正确的狀态。最後四種方法是喲娜與記憶體管理的代碼,并不适用于垃圾收集代碼。

單例設計模式。因為此模式經常引起争議,是以我想有必 要在此解釋一下單例。

原則上,單例是在程式生命周期裡隻被執行個體化過一次的 類。為了確定這一點,我們利用類的一個靜态方法來生成和通路對象。

是以, 你是通過以便利方法來通路某個類的單例對象的,而不是用 alloc/init或者靜态autorelease初始化方法。

在很多時候,我們使用一個某個類的唯一執行個體。最常見的就是一個程式的主類。

以下是以名為 rootviewcontroller 建立的一個單例函數:

static rootviewcontroller*sharedrootcontroller = nil;

+(rootviewcontroller *) sharedcontroller{

    @synchronized(self){

        if (sharedrootcontroller == nil) {

           sharedrootcontroller = [[[self alloc] init] autorelease];(#add turorelease未必好,一般不用)

        }

    }

    return  singlecontroller;

}

+(id) allocwithzone:(nszone *)zone{

           sharedrootcontroller = [super allocwithzone:zone];

            return  sharedrootcontroller;

    return nil;

 代碼說明:

1. synchronized   這個主要是考慮多線程的程式,這個指令可以将{ } 内的代碼限制在一個線程執行,如果某個線程沒有執行完,其他的線程如果需要執行就得等着。

2. 網上搜尋的代碼,好像有一個沒有加入 autorelease ,我覺得應該需要加。因為如果調用的函數沒有release 就麻煩了。(個人認為ios 上的程式,對于建立用于函數傳回值的,都應該考慮 autorelease)

3. allocwithzone 這個是重載的,因為這個是從制定的記憶體區域讀取資訊建立執行個體,是以如果需要的單例已經有了,就需要禁止修改目前單例。是以傳回 nil

繼續閱讀