2013-06-20 2 views
5

Ich versuche doppelten Code in verschiedenen -(id)init Aromen einer Klasse zu vermeiden, das heißt init, initWithFrame, initWithCoder usw. durch eine private Methode definiert, die commonConstruct gestattet.Objective-C: Wie vermeidet man unbeabsichtigte Aufrufe an private Superklassen-Methoden mit identischem Namen?

Diese Methode führt das schwere Heben von allen init-Methodenaromen durch und wird vom init-Konstruktor aufgerufen.

Das Problem, das ich jetzt habe, ist, dass Klassen in abgeleitet sind, die gleichen Namens Konvektion für den initializer Helfer („commonConstruct“) die Basisklasse commonConstruct ist die abgeleitete Klasse verwendet nennen, obwohl es invisible, dh in der .m Datei deklariert nicht in der Datei .h.

Die Laufzeit findet jedoch das überladene commonConstruct und führt das statt seiner eigenen Elementfunktion aus.

Gibt es eine andere Möglichkeit als einen anderen Namen für den Initialisiererhelfer in jeder Unterklasse zu verwenden?

Mit anderen Worten: Gibt es eine Möglichkeit, Objective-C Mitgliedsfunktionen zu machen, die "nicht virtuell" sind, d. H. Keine späte (Laufzeit), aber Kompilierungszeitbindung haben?

+0

wo ist 'commonConstruct' definiert? –

+0

commonConstruct ist in jeder Klasse @Implementation-Abschnitt definiert –

Antwort

4

Es gibt keine gute Compiler-erzwungene Möglichkeit, dies zu tun. Methoden sind immer "virtuell" und es gibt keine Durchsetzung von "privaten" Methoden.

Die gemeinsame Lösung ist, den Klassennamen in den Namen der Methode einzubetten, also:

@implementation Thing 

- (instancetype)init { 
    if (self = [super init]) { 
     [self Thing_commonInit]; 
    } 
    return self; 
} 

- (instancetype)initWithArg:(NSObject *)arg { 
    if (self = [super init]) { 
     [self Thing_commonInit]; 
     [self doSomethingWithArg:arg]; 
    } 
    return self; 
} 

- (void)Thing_commonInit { 
    ... 
} 
3

Neben Rob Mayoff-Lösung (die ich auch verwenden) eine statische C-Funktion verwenden:

Statische Funktionen geben keine Symbole aus, daher sind keine Konflikte möglich. Sie können alle gängigen Initialisierer commonInit benennen.

+0

Das ist eine gute Idee. Der einzige Nachteil ist, dass Sie den Instanzzeiger übergeben müssen. Der Vorteil besteht darin, dass Sie keine Nachrichtentabelleneinträge erstellen, die Sie nicht benötigen. –

+0

@AraschHonarbacht Ja, der Instanzenzeiger wird benötigt, um die Instanz zu initialisieren. Der einzige Unterschied bei der Verwendung einer Instanzmethode besteht darin, dass sie implizit (zusammen mit dem Selektor) statt explizit wie bei der C-Funktion übergeben wird. –

Verwandte Themen