2012-08-15 47 views
6

BNRItemStore是一個單例,我很困惑爲什麼super allocWithZone:必須被調用而不是普通的舊的super alloc。然後覆蓋alloc而不是allocWithZone使用allocWithZone創建一個單例:

#import "BNRItemStore.h" 

@implementation BNRItemStore 

+(BNRItemStore *)sharedStore { 
    static BNRItemStore *sharedStore = nil; 

    if (!sharedStore) 
     sharedStore = [[super allocWithZone: nil] init]; 

    return sharedStore; 
} 

+(id)allocWithZone:(NSZone *)zone { 
    return [self sharedStore]; 
} 

@end 

回答

10

[super alloc]將通過調用allocWithZone:,您已覆蓋做別的事情。爲了實際獲得超類的實現allocWithZone:(這是你想要的),而不是被覆蓋的版本,你必須明確地發送allocWithZone:

super關鍵字表示與self相同的對象;它只是告訴方法調度機制開始在超類而不是當前類中尋找相應的方法。

因此,[super alloc]將上升到超類,並得到執行那裏,它看起來像:

+ (id) alloc 
{ 
    return [self allocWithZone:NULL]; 
} 

這裏,self仍然是你的自定義類,因此,你的覆蓋allocWithZone:運行,這會將您的程序發送到無限循環。

+0

難倒了,這是在ObjC入門課程的一個微妙的一面,所以如果你有關於我的答案的問題,我很樂意澄清。 – 2012-08-15 01:29:06

+0

謝謝!我有一個問題。如果我刪除了重寫allocWithZone的方法:是否可以調用super alloc而不是super allocWithZone:在sharedStore中? – stumped 2012-08-15 01:31:35

+0

是的。覆蓋'allocWithZone:'的原因是限制這個類的任何用戶創建另一個實例。他們會直接調用alloc(或可能是'allocWithZone:';而不是分配一個新的實例,而是返回現有的實例,這是使這個類成爲單例的關鍵部分 – 2012-08-15 01:35:53

3

從蘋果公司的documentation

這種方法存在的歷史原因;內存區不再是Objective-C使用的 。

相關問題