2011-02-13 36 views
0

我想寫一個類,我可以繼承有一個即時單例。這是迄今爲止我所擁有的。它會一直工作,直到其中一個子類通過sharedInstance調用另一個子類,這會導致最終耗盡內存的巨大循環。Objective-C Singleton超類?

任何想法?

static NSMutableDictionary *sharedInstances = nil; 

@implementation Singleton 

+ (Singleton*)sharedInstance 
{ 
    [Singleton initSharedInstances]; 
    Class myClass = [self class]; 
    Singleton * sharedInstance = [sharedInstances objectForKey:myClass]; 
    @synchronized(myClass) 
    { 
     if (sharedInstance == nil) 
     { 
      sharedInstance = [[myClass alloc] init]; 
      [sharedInstances setObject:sharedInstance forKey:myClass]; 
     } 
    } 
    return sharedInstance; 
} 

+ (void) initSharedInstances 
{ 
    if (sharedInstances == nil) 
    { 
     sharedInstances = [[NSMutableDictionary alloc] init]; 
    } 
} 

@end 

回答

0

我試圖寫一個類,我可以子類有一個即時單例。這是迄今爲止我所擁有的。它會一直工作,直到其中一個子類通過sharedInstance調用另一個子類,這會導致最終耗盡內存的巨大循環。

這聽起來像你在描述相互遞歸。如果subclass1調用subclass2和subclass2調用subclass1,那麼你需要在某個地方打破循環,就像使用簡單的自遞歸一樣。

sharedInstance本身不應導致無限遞歸除非init方法調用本身調用sharedInstance ...

7

你爲什麼要這麼麻煩?如果您試圖通過覆蓋-retain-release-retainCount+allocWithZone:來強制執行超類中的單例行爲,那麼您正在做一些完全不必要的操作。更簡單的是隻提供一個+sharedInstance方法,不要做別的。如果用戶真的想撥打+alloc/-init,他們可以,但它不會做得很好。對於框架中的這種單例的例子,看看NSUserDefaultsNSFileManager(儘管在後者的情況下,現在Apple實際上建議你忽略共享實例並且alloc/012自己的實例NSFileManager)。

爲了做到這一點簡單的共享實例的東西,所有你需要做的就是,在單例類,具有如下功能:

+ (id)sharedInstance { 
    static MyClass sharedInstance; 
    static dispatch_once_t predicate; 
    dispatch_once(&predicate, ^{ 
     //sharedInstance = [[MyClass alloc] init]; 
     sharedInstance = [MyClass alloc]; 
     sharedInstance = [sharedInstance init]; 
    }); 
    return sharedInstance; 
} 
+2

完全一致;我發現所有單例類中的方法重寫通常都很愚蠢。它可能* *可能*在某些類中有意義,這個框架將被衆多你不認識的人使用。爲了你自己的東西?把事情簡單化!! – bbum 2011-02-13 03:05:13