2009-06-13 3 views
72

Безопасно ли рассчитывать на int s всегда инициализируется до 0 в Objective-C?Всегда ли инициализируются ints?

Более конкретно, когда объект с int ivars был вновь создан, можно ли предположить, что его ivars имеет значение 0?

ответ

110

Да, переменные экземпляра класса всегда инициализируются до 0 (или nil, NULL или false, в зависимости от точного типа данных). Смотрите Objective-C 2.0 Programming Language:

Метод alloc динамически выделяет память для переменных экземпляра нового объекта и инициализирует их все 0-все, что есть, кроме isa переменной, которая соединяет новый экземпляр этого класса.


EDIT 2013-05-08
Apple, кажется, удалили вышеуказанный документ (в настоящее время связаны с Wayback Machine). (В настоящее время) активный документ Programming With Objective-C содержит аналогичную цитату:

Метод alloc имеет одну других важную задачу, которая должна очистить память, выделенную для свойств объекта путем установки их к нулю. Это позволяет избежать обычной проблемы с памятью, содержащей мусор, из того, что было ранее сохранено, но недостаточно для инициализации объекта полностью.


Однако это только верно для переменных экземпляра класса; это также верно для типов POD объявленных в глобальной области видимости:

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

За одним исключением, это не верно для локальных переменных, или для данных, выделенных malloc() или realloc(); это верно для calloc(), так как calloc() явно выделяет память, которую он выделяет.

Единственным исключением является то, что при включении автоматического подсчета ссылок (ARC) указатели стека на объекты Objective-C неявно инициализируются до nil; однако, по-прежнему хорошей практикой явным образом их инициализировать до nil. Из Transitioning to to ARC Release Notes:

стека переменные инициализируются с nil

Использование ARC, сильный, слабый, и autoreleasing стек переменных теперь неявно инициализируется nil

В C++ (и C++ объекты, являющиеся используется в Objective-C++), переменные экземпляра класса также являются не zero-initialized. Вы должны явно инициализировать их в своих конструкторах.

+3

Пятно на. Однако тот факт, что люди часто задаются вопросом об этой детали, может быть достаточной причиной для более явной инициализации переменных, возможно, «более безопасного» выбора. Инициализация до 0/nil/NULL никогда никому не повредит ... :-) –

+0

Я согласен с Куинн. В этом случае, однако, я создаю «абстрактный» класс, который не реализует - (void) init, и я не хочу заставлять каждый подкласс запоминать инициализацию ivars. Так что хорошо знать, что я могу рассчитывать на то, что они будут инициализированы до 0. – Felixyz

+0

Мой опыт даже в режиме выпуска для iOS заключается в том, что даже локальные переменные инициализируются до 0 – jjxtra

-1

Я не думаю, что вы должны принимать какие-либо значения для инициализации. Если вы строите логику вокруг значения «0», вы должны установить ее, чтобы быть уверенным.

+0

Я предполагаю, что мы можем рассматривать это как верный ответ для C++, в то время как ответ Адама относится к Objective-C? – Felixyz

+11

Ответ Адама для Objective C точно прав - Objective C абсолютно гарантирует, что ивары установлены на nil/NULL/false/0 при распределении, и совершенно разумно принять и использовать этот факт. Например, это позволяет тривиально ленивую инициализацию NSMultableArray * ivars с помощью [NSMultableArray array или new], когда они замечены как nil. В сочетании с параметром Objective C guarentteing [(NSMultableArray *)] возвращается 0, вы можете часто отложить инициализацию еще больше. Научитесь любить то, как Objective C делает это, а не просто бороться с его различиями. –

-2

Да, в C глобальные vars инициализируются до нуля. В Objective-C даже локальные вары инициализируются до нуля. Вы можете рассчитывать на это.

+1

@ Ответ Адам Розенфилда прямо противоречит вашему утверждению, что даже локальные вары инициализируются до нуля. Кто не прав? –

Смежные вопросы