2014-01-29 81 views
0

你可以爲一個類創建一個自定義的初始化程序嗎?自定義的初始化程序沒有重寫init?

你能舉例來說事:

+ (instancetype)node { 
    BetterSKNode *newNode = [[BetterSKNode alloc]initWithRootName:@"ROOT"]; 
    return newNode; 
} 

- (id)initWithRootName:(NSString *)rootName { 
    self = [super init]; 
    if(self) { 
     _rootName = rootName; 
    } 
    return self; 
} 

,如果你做的應該是上面或self = [super init];self = [self init];

它很容易增加(見下文),但我只是好奇,如果有必要嗎?

- (id)init { 
    self = [super init]; 
    if(self) { 
     // ... 
    } 
    return self; 
} 

編輯:

技術上正確的方法是由init調用「指定初始化器」來掩蓋的可能性,有人可能在未來只需要調用[[類的alloc]初始化]

- (id)init { 
    self = [self initWithRootName:@"ROOT"]; 
    return self; 
} 
+0

'[self init]'會導致無限遞歸。你想要做什麼? –

+0

對不起,你是在問如何爲一個班級設置自定義的初始化程序? –

+0

無限遞歸,initWithRootName:調用[self init],然後[self init]調用[super init]; – fuzzygoat

回答

1

Cocoa中的約定是指定一個指定的初始化程序,它是所有其他初始程序調用的初始程序。它通常是具有最多參數的初始化程序(因爲這些可以由其他初始化程序設置爲默認值)

此外,該指定的初始化程序應該將其稱爲超類的指定初始化程序,作爲其實施的一部分。

所以你的情況,你已經在initWithRootName:指定初始化器讓你的代碼可能是這樣的:

+ (instancetype)node { 
    BetterSKNode *newNode = [[BetterSKNode alloc]initWithRootName:@"ROOT"]; 
    return newNode; 
} 

- (id)initWithRootName:(NSString *)rootName { 
    self = [super init]; // Assuming that init is the designated initialiser of the superclass 

    if(self) { 
     _rootName = rootName; 
    } 

    return self; 
} 

// If you choose to add an init, method then it should call the designated initialiser 

- (id)init { 
    return [self initWithRootName:@"ROOT"]; // use a default value for the parameter 
} 

所以,是的,你可以不覆蓋init子類。

+0

謝謝Abizern,非常感謝。 – fuzzygoat

1

使用self = [self init];可以保護您免受未來更改的影響,您可以在該類中添加init方法,但可以在將來重構時添加該方法。

請注意,您不需要實施該方法,因爲它將調度到super。如果您沒有進行任何自定義操作,請不要添加額外的代碼。

1

當然,你可以做到這一點,如果我們假設你是從NSObject繼承。 NSObject執行-(id)init並且該方法被繼承到子類。

相關問題