Werden Ints immer auf 0 initialisiert?

74

Ist es sicher, dass ints in Objective-C immer auf 0 initialisiert wird?

Wenn ein Objekt mit intIvars neu instanziiert wurde, kann man dann sicher annehmen, dass seine Ivars den Wert 0 haben?

Felixyz
quelle

Antworten:

114

Ja, Klasse Instanzvariablen werden immer auf 0 initialisiert (oder nil, NULLoder false, abhängig von dem genauen Datentyp). Siehe die Programmiersprache Objective-C 2.0 :

Die allocMethode reserviert dynamisch Speicher für die Instanzvariablen des neuen Objekts und initialisiert sie alle mit 0, dh mit Ausnahme der isaVariablen, die die neue Instanz mit ihrer Klasse verbindet.


EDIT 2013-05-08
Apple scheint das obige Dokument entfernt zu haben (jetzt mit The Wayback Machine verknüpft). Das (derzeit) aktive Dokument Programmieren mit Objective-C enthält ein ähnliches Zitat:

Die allocMethode hat eine weitere wichtige Aufgabe: Sie löscht den für die Objekteigenschaften zugewiesenen Speicher, indem Sie sie auf Null setzen. Dies vermeidet das übliche Problem, dass Speicher Speicher von allem enthält, was zuvor gespeichert wurde, reicht jedoch nicht aus, um ein Objekt vollständig zu initialisieren.


Dies gilt jedoch nur für beispielsweise Variablen einer Klasse. Dies gilt auch für POD-Typen, die im globalen Bereich deklariert wurden:

// At global scope
int a_global_var;  // guaranteed to be 0
NSString *a_global_string;  // guaranteed to be nil

Mit einer Ausnahme gilt dies nicht für lokale Variablen oder für Daten, die mit malloc()oder zugeordnet sind realloc(). Dies gilt für calloc(), da calloc()der zugewiesene Speicher explizit auf Null gesetzt wird.

Die einzige Ausnahme besteht darin, dass bei aktivierter automatischer Referenzzählung (ARC) Stapelzeiger auf Objective-C-Objekte implizit initialisiert werden nil. Es ist jedoch immer noch eine gute Praxis, sie explizit zu initialisieren nil. Vom Übergang zu ARC Versionshinweise :

Stapelvariablen werden mit initialisiert nil

Mit ARC werden nun implizit starke, schwache und automatisch freigegebene Stapelvariablen mit initialisiert nil

In C ++ (und C ++ - Objekten, die in Objective-C ++ verwendet werden) werden Klasseninstanzvariablen ebenfalls nicht mit Null initialisiert. Sie müssen sie explizit in Ihren Konstruktoren initialisieren.

Adam Rosenfield
quelle
3
Genau richtig. Die Tatsache, dass sich die Leute oft über dieses Detail wundern, kann jedoch Grund genug sein, die Initialisierung von Variablen expliziter zu gestalten, was wohl die "sicherere" Wahl ist. Die Initialisierung auf 0 / nil / NULL hat noch nie jemanden verletzt ... :-)
Quinn Taylor
4
@ PsychoDad Meine Erfahrung ist das Gegenteil.
Titandecoy
1
@Pang: Jetzt behoben. Apple hat das Originaldokument "Objective-C 2.0 Programming Language" AFAICT leider entfernt.
Adam Rosenfield
1
Unter ARC werden lokale Variablen vom Typ idebenfalls auf Null initialisiert.
LearnCocos2D
1
@ n00bProgrammer: Ja. In den oben beschriebenen Situationen werden alle Variablen auf die für ihre jeweiligen Datentypen geeignete Weise "nullinitialisiert". Arithmetic Typen ( int, NSUInteger, CGFloat, float, bool, BOOL, char, etc.) sind alle auf 0 in diesen Typen dargestellt initialisiert.
Adam Rosenfield
-1

Ich denke nicht, dass Sie Werte für die Initialisierung annehmen sollten. Wenn Sie eine Logik um einen "0" -Wert erstellen, sollten Sie ihn sicherheitshalber einstellen.

Cody C.
quelle
Ich gehe davon aus, dass wir dies als gültige Antwort für C ++ sehen können, während Adams Antwort für Objective-C gilt.
Felixyz
11
Adams Antwort für Ziel C ist genau richtig - Ziel C garantiert absolut, dass ivars bei der Zuweisung auf null / NULL / falsch / 0 gesetzt wird, und es ist durchaus sinnvoll, diese Tatsache zu akzeptieren und zu verwenden. Dies ermöglicht beispielsweise eine triviale verzögerte Initialisierung von NSMultableArray * ivars mit [NSMultableArray-Array oder neu], wenn festgestellt wird, dass sie Null sind. In Kombination mit der Ziel-C-Garantie [(NSMultableArray *) count] wird 0 zurückgegeben. Sie können die Initialisierung häufig noch weiter verschieben. Lerne zu lieben, wie es Ziel C tut, und nicht nur gegen seine Unterschiede zu kämpfen.
Peter N Lewis
-2

Ja, in C werden globale Variablen auf Null initialisiert. In Objective-C werden sogar lokale Variablen auf Null initialisiert. Du kannst dich darauf verlassen.

Tom01
quelle
1
Die Antwort von @ AdamRosenfield widerspricht direkt Ihrer Behauptung, dass sogar lokale Variablen auf Null initialisiert werden. Wer ist falsch?
Mark Amery