2010-12-08 66 views
4

有沒有辦法用objective-c創建一個Singleton模式,這將使客戶端代碼能夠獲得它的任何子類的共享實例?Objective-c singleton baseclass

我想:

@interface Base : NSObject {} 
+(id)instance; 
@end 

@implementation Base 
static id _instance; 
+(id)instance { 
    if (!_instance) { 
     _instance = [[self alloc] init]; 
    } 
    return _instance; 
} 
@end 

但任何調用子類的[AmazingThing instance]只返回通過這種機制創建的第一個實例,無論_instance是什麼類型。任何清理解決方法?

編輯

我意識到(而回復已刪除的答案),我可以做什麼,我一直在尋找通過改變執行是:

static NSMutableDictionary *_instances; 

+(id)instance { 
    if (!_instances) { 
     _instances = [[NSMutableDictionary alloc] init]; 
    } 
    id instance = [_instances objectForKey:self]; 
    if (!instance) { 
     instance = [[self alloc] init]; 
     [_instances setObject:instance forKey:self]; 
    } 
    return instance; 
} 

現在按預期工作。不過,我很想知道是否有更好的方法來做到這一點。

+0

只是出於好奇,這是什麼用例呢? – ennuikiller 2010-12-08 01:23:22

+0

@ennuikiller我正在製作一個實體/組件系統,並且爲了建立原型,我希望每個組件都有一個單例。 – sharvey 2010-12-08 01:38:18

+0

你的編輯在我的情況下是相當不錯的解決方案。謝謝! – Adem 2015-11-01 21:16:36

回答

7

我會做這樣的:

+(id) instance 
{ 
    static id theInstance = nil; 
    if (theInstance == nil) 
    { 
     theInstance = [[self alloc] init]; 
    } 
    return theInstance; 
} 

當然你需要在你的基類的每個子類中該方法以獲得針對每個類別不同的​​靜態變量。但是,你將創建一個基礎類的頭一個#define

#define CREATE_INSTANCE   \ 
+(id) instance     \ 
{         \ 
    static id theInstance = nil; \ 
    if (theInstance == nil)  \ 
    {        \ 
     theInstance = [[self alloc] init]; \ 
    }        \ 
    return theInstance;   \ 
} 

,然後將每個impementation只是在它的定義:

@implementation SubClass 

CREATE_INSTANCE 

// other stuff 

@end 
0

只需使用EPPZSingleton

要創建一個只能有一個子類的基類很簡單,但是當您開始創建越來越多的子類時,可能會出現不必要的行爲。 EPPZSingleton通過維護一個共享的單例集合來解決這個問題。