2010-12-05 2 views
36

In Objective-C ist es erforderlich, alle geerbten Konstruktoren einer Unterklasse zu überschreiben, um benutzerdefinierte Initialisierungslogik hinzuzufügen?Init in Unterklasse überschreiben

Zum Beispiel würde das Folgende für eine UIView Unterklasse mit benutzerdefinierter Initialisierungslogik korrekt sein?

@implementation CustomUIView 

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

- (id)initWithFrame:(CGRect)theFrame { 
    self = [super initWithFrame:theFrame]; 
    if (self) { 
     [self initHelper]; 
    } 
    return self; 
} 

- (id)initWithCoder:(NSCoder *)decoder { 
    self = [super initWithCoder:decoder]; 
    if (self) { 
     [self initHelper]; 
    } 
    return self; 
} 

- (void) initHelper { 
    // Custom initialization 
} 

@end 

Antwort

38

Jede Cocoa Touch (und Cocoa) -Klasse hat einen designierten Initialisierer; für UIView, wie angegeben in this documentation, ist diese Methode initWithFrame:. In diesem speziellen Fall müssen Sie nur initWithFrame überschreiben; Alle anderen Aufrufe kaskadieren und treffen schließlich diese Methode. Diese

geht über den Rahmen der Frage, aber wenn Sie eine benutzerdefinierte initializer mit zusätzlichen Parametern zu schaffen machen landen, sollten Sie auf die benannten Initialisierer für die übergeordnete Klasse stellen Sie sicher, wenn self zuweisen, wie folgt aus:

- (id)initWithFrame:(CGRect)theFrame puzzle:(Puzzle *)thePuzzle title:(NSString *)theTitle { 
    self = [super initWithFrame:theFrame]; 
    if (self) { 
     [self setPuzzle:thePuzzle]; 
     [self setTitle:theTitle]; 
     [self initHelper]; 
    } 
    return self; 
} 
+1

Also selbst wenn ich Instanz CustomUIView mit einfachen init, wird es Initwithframe nennen? – hpique

+0

Das ist richtig. Die Möglichkeit, dies zu testen, besteht darin, sowohl init: als auch initWithFrame: zu überschreiben, in der ersten Zeile Haltepunkte (oder NSLog-Anweisungen) und init die Instanz CustomUIView festzulegen. Sie sollten sehen, dass init zuerst und dann initWithFrame: aktiviert wird. –

+29

Was zu beachten ist, ist, dass, wenn ein Objekt von einer NIB instanziiert wird, 'initWithCoder:' aufgerufen wird, und ** NOT ** 'initWithFrame:'. – Pascal

4

Im Allgemeinen sollten Sie die angegebene Initialisierungskonvention befolgen. Der designierte Initialisierer ist das Init, das die Initialisierung aller Instanzvariablen abdeckt. Der designierte Initialisierer ist auch die Methode, die von anderen Init-Methoden einer Klasse aufgerufen wird.

Apples documentation über designierte Initialisierer.

initWithFrame: ist der designierte Initialisierer der NSView-Klasse. Apples Cocoa-Dokumentation erwähnt immer ausdrücklich den designierten Initialisierer einer Klasse.

initWithCoder: ist diskutiert here on SO.

2

Bei Interface Builder verwenden, wird derjenige genannt ist:

- (id)initWithCoder:(NSCoder *)coder 
{ 
    self = [super initWithCoder:coder]; 
    if (self) { 
     //do sth 
    } 
    return self; 
} 
Verwandte Themen