Was macht Objective-C eigentlich, wenn Sie ein Objekt deklarieren?

8

Ich habe die Speicherverwaltung von Apple gelesen und sehe nicht, wo dieser Fall erklärt wird ...

Viele Male, vor allem beim Schreiben einer Klassenmethode zum Zurückgeben einer Instanz einer Klasse, starte ich so, denn so habe ich es gesehen, und es funktioniert.

[NOTE] Dieser Code stammt aus dem Speicher - ich werde ihn aktualisieren, wenn ich nach Hause komme, um ein Beispiel zu zeigen, das wirklich funktioniert (ich habe es erfunden, um es zu illustrieren, aber ich erinnere mich nicht gut genug, um etwas zu konstruieren das macht Sinn ...

[EDIT] Hier ist meine aktuelle Methode - natürlich hatten alle Recht, dass ich alloc aufrufen musste, was ich bin.

%Vor%

Was ich von den Antworten bekommen habe, ist:   * Das Deklarieren der Instanz erhält nur einen Zeiger auf einen Speicherort und teilt Xcode mit, welche Klasse das Objekt sein wird.   * Wenn man den Zeiger auf Null setzt, wird er einfach auf Null gesetzt - es wird kein Müll drin sein (richtig?)   * Da ich die Instanz automatisch wiederöffne, wird auch das zurückgegebene Objekt automatisch freigegeben.

Danke, dass du mir geholfen hast, das zu verstehen!

    
Steve 10.06.2011, 18:58
quelle

3 Antworten

11
  

Kann jemand erklären, was der Compiler macht, wenn er das sieht?

%Vor%

Wenn Sie wirklich interessiert sind, was der Compiler macht, lautet die Antwort: Der Compiler reserviert etwas Speicher auf dem Stack für die lokale Variable aDooDad , die ein Zeigertyp ist (normalerweise 64 oder 32 Bit groß) abhängig vom Prozessor). Dieser Zeiger wird dann initialisiert, um nil (normalerweise 0x00..00 ) zu enthalten.

Eine Aussage wie diese:

%Vor%

verwendet die Zeigervariable aDooDad , um die Adresse im Speicher des Objekts zu speichern, das weiter zugeordnet wird (dies ist die Adresse des reservierten Speichers von alloc ).

Also, am Ende,

%Vor%

deklariert kein Objekt, sondern nur eine Variable, deren Inhalt als Adresse eines Objekts von DooDad type interpretiert wird. Eine solche Deklaration ist daher genau wie jede andere Deklaration, die Sie kennen, z. bei der Initialisierung von int auf 0, damit Sie später einen Wert in einer if -Anweisung zuweisen können.

Eine Aussage wie:

%Vor%

wird vom Objective-C-Laufzeitsystem wie folgt interpretiert: Senden Sie die Nachricht doSomething an das Objekt, dessen Adresse in aDooDad gespeichert ist. Wenn diese Adresse nil ist, wird keine Nachricht gesendet. Auf der anderen Seite, wenn Sie Dereferenzierung einen Nullzeiger: *aDooDad erhalten Sie undefiniertes Verhalten.

Pointer sind ziemlich low-level Zeug. Ich hoffe, das hilft.

    
sergio 10.06.2011, 19:12
quelle
4

Wenn Sie mit C oder C ++ vertraut sind, können Variablen auf zwei Arten erstellt werden, statisch auf dem Aufruf-Stack oder dynamisch auf dem Heap. Variabler Speicher, der auf dem Stack erstellt wurde, wird zurückgewonnen, wenn der aktuelle Stack-Frame den Bereich verlässt. Sie müssen sich also nie darum kümmern, ihn zu erstellen oder zu zerstören. In Objective-C werden Objekte immer dynamisch erstellt. Primitive (wie int, float, pointer, etc.) können entweder statisch oder dynamisch erstellt werden. Zur Veranschaulichung:

%Vor%

Wenn Sie also DooDad* dodad = nil; sagen, erstellen Sie ein primitives Element (Zeiger auf ein DooDad) auf dem Stapel. Da es sich um eine Stapelvariable handelt, wird sie nicht zugewiesen oder freigegeben, genau so, als würden Sie sich keine Sorgen darüber machen, wie Sie den Speicher in der folgenden Methode zuweisen oder freigeben:

%Vor%

Wenn Sie ihn auf nil setzen, wird der Inhalt der Variablen einfach auf den Wert gesetzt, den der Compiler als nil definiert, etwa 0x000000 in hexadezimal. Das Sagen von DooDad* dooDad = nil; ist konzeptionell identisch mit etwas wie int myInt = 0;

    
Matt Wilding 10.06.2011 19:23
quelle
2

Wenn Sie einfach deklarieren, erhalten Sie einen Zeiger, den Sie später verwenden können. Kein Speicher ist zugewiesen.

Nicht sicher, was die Absicht der von Ihnen geposteten Methode ist, aber es scheint auf vielen Ebenen falsch zu sein. Es wird immer Null zurückgeben. Sofern es sich nicht um eine Initialisierungsmethode handelt, sollte [self init] nicht aufgerufen werden. Wenn es eine Initialisierungsmethode ist, sollte es sich selbst zurückgeben und so etwas wie "init ..."

heißen     
picciano 10.06.2011 19:04
quelle