Frage

Hinweis: Ich bin relativ neu in Objective-C und komme aus Java und PHP

.

Könnte mir jemand erklären, warum ich immer zuerst müssen zuweisen und dann eine Instanz initialisieren?

Könnte dies nicht in den init Methoden wie dies getan werden:

+ (MyClass*)init {
    MyClass *instance = [MyClass alloc];
    [instance setFoo:@"bla"];

    return instance;
}

+ (MyClass*)initWithString:(NSString*)text {
    MyClass *instance = [MyClass init];
    [instance setFoo:text];

    return instance;
}
...

Ist das nur ein Relikt aus den alten C Tagen oder gibt es etwas, dass ich sehe nicht?

Ich weiß, das ist kein Problem, da ich könnte auch rufen immer alloc und init, aber da es ein bisschen langweilig ich zumindest wissen möchte, warum ich es mache.

Ich bin gefallen die Ausdruckskraft der Sprache so weit, aber das ist etwas, dass ich will, um vollständig zu verstehen, die Objective-C Art und Weise zu denken.

Danke!

War es hilfreich?

Lösung

+ neue endet eine + alloc Nachricht an die Klasse zu senden und eine -init Nachricht an, was auch immer von + alloc kommt zurück.

Der Grund, dass NeXT von Stepstone Konvention verließ die + neue Nachricht der Verwendung (das ist eine Smalltalk Idee war) ist, dass früh, sie Situationen angetroffen, wo sie wollten mehr das gleiche Objekt zu initialisieren, um die Lage sein, als einmal.

Andere Tipps

Da eine Instanz erstellen und Initialisieren einer Instanz werden zwei separate Arbeitsplätze.

Sie senden an die Klasse eine alloc Nachricht eine nicht initialisierte Instanz zu erhalten. Sie müssen dann die Instanz initialisieren, und Sie oft mehr Möglichkeiten haben, das zu tun. Zum Beispiel:

myStr = [[NSString alloc] init]; //Empty string
myStr = [[NSString alloc] initWithFormat:@"%@.%@", parentKeyPath, key];
myStr = [[NSString alloc] initWithData:utf16data encoding:NSUnicodeStringEncoding error:&error];
myStr = [[NSString alloc] initWithContentsOfURL:URL encoding:NSUTF8StringEncoding error:&error];

Jede dieser initialisiert die Zeichenfolge in eine ganz andere Art und Weise. Wie Sie initialisieren die Zeichenfolge hängt davon ab, was Sie von ihm initialisieren möchten.

Natürlich mag niemand alloc schreiben und dann init und dann jedes Mal autorelease, so dass Sie in der Regel üblichen Methoden haben (zum Beispiel stringWithFormat:), das tut alle drei Schritte für Sie.

Edit: Weitere Informationen zu diesem Thema, einschließlich der wesentlichen Erkenntnisse aus commen finden Sie in meinem Blog-Eintrag „ Wiedervereinigung “.

Siehe NSZone.

+alloc ist eine Abkürzung Schnitt für +allocWithZone:, die einen Mechanismus ist Cocoa Speicherzuweisung für die Optimierung bietet.

So haben Sie die Möglichkeit, so etwas zu tun:

foo = [[NSString allocWithZone:MyZone] initWithString:@"Foo"];
foo2 = [foo copyWithZone:MyZone];

Die Idee hinter Speicherzonen ist, dass, wenn Sie eine große Anzahl von ähnlichen Objekten, die häufig zugeordnet und ausgeplant kann es effizienter, einen separaten Speicherbereich für diese Objekte zu verwenden.

Damit Zoning wirksam sein Sie +allocWithZone: zur Verfügung zu jeder NSObject Unterklasse haben würden wollen, daher müssen Sie gesonderte Zuweisung und Initialisierung. Sie können alle die Verknüpfungen erstellen und verwenden Sie, wie +new wollen, aber unter all dem Sie eine -init Methode benötigen, die ein Objekt initialisiert, die bereits zugeordnet wurde.

"Die Trennung der Zuordnung und Initialisierung Phasen der Instanzerstellung bietet viele Vorteile. Es ist möglich, jede Veränderung der + alloc Klassenmethode zu verwenden, um eine Instanz zuzuweisen und verwenden dann alle verfügbaren initializer mit den neuen instance.This macht es möglich, eigene Initialisierungsmethoden zu erstellen, ohne dass alternative Implementierungen aller Zuteilungsmethoden zur Verfügung zu stellen zu müssen. Neue Zuordnungsverfahren entstehen selten, weil die bestehenden Methoden fast jeden Bedarf erfüllen. Doch ein oder mehr neue initializers sind für fast jede Klasse erstellt. Durch die Trennung der Zuweisung und Initialisierung Stufen, initializer Implementierungen müssen nur mit den Variablen der neuen Instanzen beschäftigen und sur- die Probleme völlig ignorieren kann allocation.The Trennung Abrunden der Prozess des Schreibens initializers vereinfacht. Darüber hinaus Cocoa Standard initializers wie -initWithCoder: Arbeit mit Fällen, unabhängig von der Art und Weise Speicher für die Instanz zugewiesen wurde. Eine negative Folge der Trennung der Zuweisung und Initialisierung ist die Notwendigkeit bewusst, Konventionen zu sein wie der bezeichneten initializer.You müssen wissen, welche Methoden bezeichneten initializers und wie zu erstellen und zu dokumentieren neue initializers in Unterklassen. Auf lange Sicht, mit der Software-Entwicklung vereinfacht bezeichnet initializers, aber es ist ein Argument gemacht werden, dass theTwo-Bühne Creation Muster für Cocoa-Entwickler aus dem frühen Lernkurve erstellt. "


(c) Cocoa Design Patterns von Erik M. Buck und Donald A. Yacktman

Sie haben nicht zu tun. Sie können [MyClass new] verwenden. Dies ist ähnlich wie Ihre hypothetische init Methode.

Im Grunde genommen, Objective-C, die Garbage Collection zunächst nicht haben, trennt sich das Konzept der Speicherzuweisung und Klasseninitialisierung. Aus diesem Grunde gibt es zwei verschiedene Methoden. Wenn Sie alloc aufrufen, werden Sie explizit Speicher zugewiesen wird.

Die meisten Klassen haben, was Sie fordern. Sie haben Antworten bekommen, bevor sie auf, warum dies ist, wie es ist und warum Sie nicht immer würde dies die ganze Zeit nutzen wollen, aber wenn Sie in der Dokumentation zu Klassen lesen, werden Sie viele Klassenmethoden sehen, die auf diese Weise handeln, und sie werden oft verwendet.

Für NSString Sie haben, zum Beispiel:

+ (id)string  // (Empty string)
+ (id)stringWithFormat:...  // Formatted string (like you use)
+ (id)stringWithContentsOfURL:... // String populated with contents of URL

Und so weiter. Und Sie würden dann diese verwenden wie: NSString *myString = [NSString stringWithFormat:@"Hello %@\n", userName];

Die meisten anderen Klassen haben diese, wie NSArray:

+ (id)array
+ (id)arrayWithContentsOfFile:...
+ (id)arrayWithContentsOfURL:...
+ (id)arrayWithObjects:...

Sie müssen nur die Dokumentation zu lesen. :) Und lesen Sie die anderen Antworten auf, warum Sie nicht möchten, dass dies zu viel verwenden.

alloc : Speicher zugewiesen / gegeben zum Objekt-Referenz. Nun Bezug hat den Besitz des Speichers aber hat noch nichts getan. Dieser Speicher leer (seltensten Fall) oder mit einem anonymen Daten.

alloc und init : Allocated Speicher gereinigt / Entladung. Der Speicher wird eingeleitet durch Null-Bit.

alloc und initwithdata ... :. Allocated Speicher mit den gewünschten Daten zu respektieren Eigenschaften der Klasse initiiert

Zum Beispiel, wenn Sie ein Grundstück kaufen erhalten Sie den Besitz. Dieses Grundstück ist dir gegeben, wie es ist, ruiniert Ziegel oder altes Haus dort sein kann. Dies ist alloc .

Wenn Sie Ihr Grundstück reinigen und von Schmutz und Abfall entfernen. Dies ist alloc mit init.

Wenn Sie, dass in einigen wertvollen Haus bauen wird es für Sie von Bedeutung. Und es ist alloc initwith ...

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top