2012-09-03 75 views
0

我在BNR第3版中看到了一個做靜態單例類的例子。 要做到這一點,他們解釋如何避免創建循環調用超ALLOC:動態鏈接/動態輸入objective-c

static MyClass *myclass = [[super alloc] init]; 

MyClass的有自己的init方法。

NSObject -> MyClass 

我的疑問是:哪個init類被髮送? NSOject init或MyClass的init已

嵌套頁頭初始化等於:

myclass = [super alloc]然後 myclass = [myclass init] ???????????

OR

myclass = [super alloc]然後myclass = [super init]

+0

你在哪裏找到這段代碼?它看起來不正確。這段代碼是否被放在'alloc'方法中? –

+0

大書呆子牧場第3版。它是在方法裏面:+(Myclass *)sharedStore – gesnazo

+0

我會試着在nslog消息中跟蹤在alloc初始化序列中的myclass – gesnazo

回答

2

不要使用super,但不要使用self。否則你的單例的子類將無法工作。正確的方法是這樣的:

+ (MyClass *)sharedInstance { 
    static MyClass *instance = nil; 
    static dispatch_once_t onceToken; 
    dispatch_once(&onceToken, ^{ 
    instance = [[self alloc] init]; 
    }); 
    return instance; 
} 

dispatch_once保證你的代碼(在這種情況下塊)被調用一次。並且self保證子類化將正常工作。

0

對你的問題,選擇總是呼籲子類的實現,這是你的第一個猜測

書中所描述的方法是實行單有效的方式,但我不不過建議它。 Robert Vojta的解決方案很好。

我看不出需要覆蓋allocWithZone,那麼你還需要確保init什麼也不做(至少不漏)

+0

謝謝,我需要澄清在你測試中調用 – gesnazo

0

只是爲了增加一些測試:

我已經創建了2 MyClass的類: NSObject的 - > MYCLASS - > My2ndClass

所以:

@implementation Myclass 
    +(id) sharedClass { 
    static Myclass *miclase = nil; 
    miclase = [[self alloc] init];  
    NSLog(@"%@", [super description]); 
    return miclase; 
} 

-(id)init {  
    self = [super init]; 
    NSLog(@"init de Myclass"); 
    return self; 
} 
-(NSString *)description { 
    return @"i am Myclass"; 
} 
@end 

AND:

@implementation My2ndClass 
+(id) sharedClass { 
    static My2ndClass *miclase = nil; 
    miclase = [[super alloc] init]; 
    //miclase = [super init]; CRASH 
    NSLog(@"%@", [super description]); 
    return miclase; 
} 

-(id)init {  
    self = [super init]; 
    NSLog(@"init de My2ndClass"); 
    NSLog(@"%@", [super description]); 
    return self; 
} 

-(NSString *)description { 
    return @"i am My2ndClass"; 
} 
@end 

然後在AppDelegate中:

Myclass *miclase = [Myclass sharedClass]; 
My2ndClass *mi2ndclase = [My2ndClass sharedClass]; 

這是控制檯輸出:

2012-09-03 17:18:55.742 Dynamic Typing[2891:207] init de Myclass 
2012-09-03 17:18:55.744 Dynamic Typing[2891:207] Myclass 
2012-09-03 17:18:55.746 Dynamic Typing[2891:207] init de Myclass 
2012-09-03 17:18:55.747 Dynamic Typing[2891:207] init de My2ndClass 
2012-09-03 17:18:55.748 Dynamic Typing[2891:207] i am Myclass 
2012-09-03 17:18:55.751 Dynamic Typing[2891:207] My2ndClass 

像xlc0212告訴記者,當他們被嵌套在正確的消息是:

miclase = [super alloc]; 
miclase = [miclase init]; 

此外,如果我做

miclase = [super alloc] 

然後

miclase = [super init] 

崩潰。

當發送類方法(+)[super description]時,它會記錄類名(Myclass和My2ndClass)。他們本身就是上課,沒有超級對象,是嗎?

+0

的子類,'super'類方法代表超類的類對象,它沒有實現'+(id)init'方法,所以它崩潰了 –