+initalize
wird zum ersten Mal an eine Klasse gesendet, wenn sie oder eine ihrer Unterklassen zum ersten Mal eine Nachricht empfängt. Also, wenn Sie das tun:
instance = [[[YourClass alloc] init] autorelease];
Die alloc
Nachricht initialize
auslöst.
Wenn Sie das Gleiche mit einer Unterklasse zu tun:
instance = [[[SubclassOfYourClass alloc] init] autorelease];
Die alloc
Nachricht auslösen +[YourClass initialize]
die gleiche Art und Weise hat die anderen (vor dem Auslösen auch +[SubclassOfYourClass initialize]
Aber nur einer von ihnen wird it- tun. jede initialize
Klasse wird nie mehr als einmal aufgerufen. (es sei denn, Sie es selbst nennen mit [super initialize]
oder [SomeClass initialize]
-so das nicht tun, weil die Methode es nicht erwartet wird.)
-init
, auf der anderen Seite, initialisiert eine neue Instanz Im Ausdruck [[YourClass alloc] init]
senden Sie die Nachricht persönlich direkt an die Instanz. Sie können es auch indirekt über einen anderen Initialisierer ([[YourClass alloc] initWithSomethingElse:bar]
) oder eine Convenience Factory ([YourClass instance]
) aufrufen.
Im Gegensatz zu initialize
sollten Sie immer init
(oder einen anderen Initialisierer, falls zutreffend) an Ihre Oberklasse senden. Die meisten init Methoden aussehen grob wie folgt aus:
- (id) init {
if ((self = [super init])) {
framistan = [[Framistan alloc] init];
}
return self;
}
Details unterscheiden (diese Methode oder die Superklasse oder beide Argumente annehmen kann, und einige Leute bevorzugen self = [super init]
auf seine eigene Linie und Wil Shipley doesn't assign to self
at all), aber die Grundidee ist die gleiche : Rufen Sie [super init[WithSomething:…]]
, stellen Sie sicher, dass es nil
nicht zurückgegeben hat, richten Sie die Instanz ein, wenn dies nicht der Fall ist, und geben Sie zurück, was auch immer die Oberklasse zurückgegeben hat.
Dies bedeutet, dass Sienil
von init
zurückkehren können, und in der Tat können Sie. Wenn Sie dies tun, sollten Sie [self release]
, damit Sie das fehlerhafte Objekt nicht verlieren. (Für ungültige Argumentwerte zu erfassen, ist eine Alternative NSParameterAssert
, die eine Ausnahme auslöst, wenn die Behauptung fehlschlägt. Die relativen Vorzüge sind jeweils über den Rahmen dieser Frage.)
Wie kann ich diese verwenden, um eine Instanz zu erstellen von meinem AppController mit Instanzvariablen, die meine Schnittstelle ausmachen?
Der beste Weg ist es alles in main
zu tun:
int main(int argc, char **argv) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
AppController *controller = [[[AppController alloc] init] autorelease];
[[NSApplication sharedApplication] setDelegate:controller]; //Assuming you want it as your app delegate, which is likely
int status = NSApplicationMain(argc, argv);
[pool drain];
return status;
}
Sie werden in Ihrer Anwendung in AppController
Delegatmethoden anderes Set-up tun.
Das wissen Sie bereits, aber für jeden, der dies liest: Nibs sind dein Freund. Interface Builder ist dein Freund. Kämpfen Sie nicht mit der Framework-Arbeit und bauen Sie Ihre Schnittstelle grafisch auf, und Ihre Anwendung wird dafür besser sein.
Danke eine Tonne, das hat geholfen, aber es sieht aus wie IB ziemlich viel tut. Ich habe eine Methode in AppController namens load interface erstellt und in main aufgerufen. AppController * Controller = [...] [Controller LoadInterface]; Wenn ich versuche, einen Wert zu meinem Controller Variable Hauptfenster zuweisen, (continue Kommentar) ... – cemulate
erhalte ich Konsole Fehler: _NXCreateWindow: Fehler Einstellungsfenster Eigenschaft (1002) _NSSetWindowTag, Fehler Clearing Fenster Tags (1002) _NSSetWindowTag , Fehlereinstellung Fenster-Tags (1002) Kann dies behoben werden? – cemulate
Sie müssen NSApplication ausführen, bevor Sie Fenster erstellen können. Deshalb ist es besser, Ihren Controller zum Anwendungsdelegaten zu machen und Fenster in Ihren Delegiertenmethoden zu erstellen/zu laden. (Beachten Sie, dass Befehlszeilen-Apps * keine * Fenster erstellen können, weil sie NSApplication noch nicht ausgeführt haben und dies auch nie tun werden.) –