iOS中的單例

2021-07-06 01:07:36 字數 4041 閱讀 2993

單例模式用於當乙個類只能有乙個例項的時候,通常情況下這個「單例」代表的是某乙個物理裝置比如印表機,或是某種不可以有多個例項同時存在的虛擬資源或是系統屬性比如乙個程式的某個引擎或是資料。用單例模式加以控制是非常有必要的。

單例模式需要達到的目的

1. 封裝乙個共享的資源

2. 提供乙個固定的例項建立方法

3. 提供乙個標準的例項訪問介面

單例模式的建立

本文以建立乙個mysingletonclass的單例模式為例。首先,我們需要定義乙個類mysingletonclass.

[cpp]view plaincopy

@inte***ce mysingletonclass:nsobject   

並且為其新增乙個類方法(注意,這裡不是例項方法)+(id)sharedinstance;乙個基本的實現寫法如下:

[cpp]view plaincopy

staticmysingletonclass *sharedcldelegate = nil;  

+(mysingletonclass *)sharedinstance  

}returnsharedcldelegate;  

}  

在上面的**中(用到了關鍵字@synchronized是為了保證我們的單例的執行緒級別的安全,可以適用於多執行緒模式下。)static變數sharedcldelegate用於儲存乙個單例的指標,並且強制所有對該變數的訪問都必須通過類方法+(id)sharedinstance,在對+(id)sharedinstance第一次呼叫時候完成例項的建立。這裡值得留意一下的是,上面**中用的是[[selfclass] alloc],而不是[mysingletonclass alloc],一般情況下這兩種寫法產生同樣的效果,但是這裡這樣做是為了更好的利用oop的性質,[selfclass]可以動態查詢並確定類的型別從而便於實現對該類的子類化。

對例項化的控制

為了完全的實現例項的單態性,必須通過一定手段來避免例項多次被建立。+(id)sharedinstance控制了單例的建立和訪問,但是並不能控制其它地方的**通過alloc方法來建立更多的例項,因此我們還要過載任何乙個涉及到allocation的方法,這些方法包括   +new, +alloc,+allocwithzone:, -copywithzone:, 以及 -mutablecopywithzone: 另外,+(id)sharedinstance也需要稍作修改。

[cpp]view plaincopy

+ (id)hiddenalloc  

+ (id)alloc  

+ (id)new

+(id)allocwithzone:(nszone*)zone  

-   (id)copywithzone:(nszone *)zone  

- (id)mutablecopywithzone:(nszone *)zone  

+(id)sharedinstance修改如下:

+ (mysingletonclass *)sharedinstance   

}returnsharedcldelegate;  

}  

如果不考慮類的子類化,+hiddenalloc這個方法可以省略。由於我們是用[selfclass]來實現型別的動態識別,用[[selfclass] hiddenalloc]可以避免呼叫到被過載過的alloc方法。此外,hiddenalloc也為可能的子類化提供了乙個呼叫原始alloc方法的機會。上面過載過的alloc方法只是給出乙個log資訊並且返回nil。copying方法裡只是簡單的增加了retain的計數並沒有返回乙個新的例項。這也正體現了單例模式的性質,因為技術上來講,拷貝乙個單例是錯誤的(因為是「單例」)所以在copywithzone方法中我們給出了乙個錯誤資訊,當然也可以扔出乙個exception。

單例的銷毀

[cpp]view plaincopy

+ (void)attemptdealloc    

值得注意的是,上面這個attemptdealloc方法顧名思義,只是試圖釋放掉這個單例。如果retain的計數不為1,說明還有其他地方對該單例傳送過retain訊息。考慮到乙個單例模式的生存週期是整個程式結束為止。所以,在程式的任何乙個地方都沒有必要向這個單例傳送retain訊息,即便是對這個單例有引用。而是呼叫sharedinstance方法來引用這個單例,這樣做是安全的,也是合乎單例模式的技術含義的。

ios中的單例模式應用

ios中的單例模式

在objective-c中要實現乙個單例類,至少需要做以下四個步驟:

1、為單例物件實現乙個靜態例項,並初始化,然後設定成nil,

2、實現乙個例項構造方法檢查上面宣告的靜態例項是否為nil,如果是則新建並返回乙個本類的例項,

3、重寫allocwithzone方法,用來保證其他人直接使用alloc和init試圖獲得乙個新實力的時候不產生乙個新例項,

4、適當實現allocwithezone,copywithzone,release和autorelease。

下面以surveyruntimedata為例子:

static surveyruntimedata *sharedobj = nil; //

第一步:靜態例項,並初始化。

@implementation surveyruntimedata

+ (surveyruntimedata*) sharedinstance  //

第二步:例項構造檢查靜態例項是否為

nil

}return sharedobj;

}+ (id) allocwithzone:(nszone *)zone //

第三步:重寫

allocwithzone方法

}return nil;

}- (id) copywithzone:(nszone *)zone //

第四步

- (id) retain

- (unsigned) retaincount

- (oneway void) release

- (id) autorelease

- (id)init

}@end

單例是指靜態分配的例項,而iphone sdk 中全是這種例項,例如

將類方法與單例相結合,便可以在程式的任何地方訪問靜態例項,而無需使用指向物件的指標或儲存它的例項變數。建立類的唯一例項(普通單例)的函式示例:

//在很多時候,我們使用某個類的唯一例項。最常見的就是乙個程式的主類,以下是以名為rootviewcontroller 建立的乙個單例函式:

static rootviewcontroller *sharedrootcontroller = nil;

+(rootviewcontroller *) sharedcontroller   

}return sharedrootcontroller; 

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

}   

return nil; }

**說明:

1、synchronized 這個主要是考慮多執行緒的程式,這個指令可以將 內的**限制在乙個執行緒執行,如果某個執行緒沒有執行完,其他的執行緒如果需要執行就得等著。

2、網上搜尋的**,好像有乙個沒有加入autorelease,我覺得應該需要加。因為如果呼叫的函式沒有release就麻煩了(我覺得,ios 上的程式,對於建立用於函式返回值的,都應該考慮autorelease)。

3、allocwithzone 這個是過載的,因為這個是從制定的記憶體區域讀取資訊建立例項,所以如果需要的單例已經有了,就需要禁止修改當前單例,所以返回nil

iOS中的單例模式

單例模式的意思就是只有乙個例項。單例模式確保某乙個類只有乙個例項,而且自行例項化並向整個系統提供這個例項。這個類稱為單例類。單例模式的特點 顯然單例模式的特點有三個 一是某個類只能有乙個例項 二是它必須自行建立這個例項 三是它必須自行向整個系統提供這個例項。例項過程 static databasem...

iOS中的單例建立

很多人實現單例會這樣寫 implementation xxclass id sharedinstance return sharedinstance 相比之下 implementation xxclass id sharedinstance return sharedinstance 使用dispa...

ios中單例模式

單例模式的意思就是只有乙個例項。單例模式確保某乙個類只有乙個例項,而且自行例項化並向整個系統提供這個例項。這個類稱為單例類。import inte ce singleton nsobject singleton getinstance end implementation singleton sin...