2009-11-18 2 views
3

Две части по этому вопросуЯвляется ли (obj && obj! = Nil) правильным и необходимым?

1) Это понимание того, что происходит правильно?
«if (obj)» проверяет, не указана ли указатель 0x0, ака, установленная на целочисленный адрес памяти
«if (obj! = Nil)» сравнивает адрес памяти объекта с адресом памяти универсальный нулевой объект

2) Итак, в ситуации, когда я не знаю, указывает ли какая-либо переменная на что-либо, и если это так, я также не знаю, является ли этот объект допустимым объектом или нулем. Я хочу делать множество вещей на основе этой информации, а не просто передавать сообщение obj, которое, как я понимаю, будет безопасным, если оно будет нулевым. Является ли этот код правильным и необходимым?

if (obj && obj != nil) { 
    // Do a bunch of things that should only happen if obj is pointing to a valid object 
    [obj someMessage]; 
    [anotherObj someOtherMessage]; 
} 

Спасибо, ребята!

ответ

17

Исправить? Да. Необходимо? Нет. Objective-C просто #define s nil до (void *)0, что на C-терминах неверно. Поэтому просто написать

if (obj) { 
    [obj someMessage]; 
    [anotherObj someOtherMessage]; 
} 

достаточно. Кроме того, поскольку Objective-C имеет сообщение nil, вы можете просто опустить проверку в некоторых случаях. (Например, если вторая линия не была там в if блоке, вы могли бы просто назвать [obj someMessage] без разбора.)

+0

Как вы 'typedef' значение? ;) –

+0

Упс. Исправлена. Спасибо, Павел. –

+0

Некоторые другие ответы кажутся правильными, но я думаю, что этот человек лучше всего объясняет, что происходит. – DougW

12

Это правильно, в том смысле, что оно даст вам результат, которого вы ожидаете, но избыточным. Это достаточно просто использовать:

if (obj) { 

или

if (obj != nil) { 
+2

Большое спасибо за ответ. Приоритет для правильности, но я собираюсь отметить Бен как ответ для объяснения причин этого. – DougW

0

если (объект == ноль), то если (объект) будет оценивать ложь. Вам не нужны оба.

+0

Извините за нижний план, я действительно не хотел понижать этот показатель, когда я нажал на ответ Виагры. Я не могу проголосовать за то, что он слишком долго, но я не буду голосовать, когда вы редактируете сообщение. – Joost

4

Вы можете просто использовать if (obj). Согласно objc.h, nil является #define для __DARWIN_NULL. Выказывая в /usr/include/sys/_types.h, мы видим, что __DARWIN_NULL определяется как 0L, 0, или (void *)0, в зависимости от платформы и от того, используете ли вы компилятор C или C++. Но в конце концов, nil всегда оценивает значение false, поэтому достаточно простого if (obj).

4

Непосредственный ответ на ваш вопрос, но на вопрос, как это подразумевается в части 2: Невозможно определить, ссылается ли указатель на «действительный объект», кроме отправки сообщения, и если он делает то, что вы хотеть. Есть все виды вещей, которые не ноль, но все же не являются тем, что можно было бы считать «действительным объектом» для большинства целей.Например, переменная объекта может указывать на:

  • мусорного пространства, где перераспределен объект жил
  • Новый объект, который был выделен в месте объекта переменного должна указывать на
  • ИНТ, что вы случайно установить переменную
  • строку переменного тока, который вы случайно установить переменную вместо NSString

Там нет никакого способа, чтобы проверить во время выполнения, если любой из них являются саз е. Вы должны убедиться, что ваш код свободен от ошибок, которые помещают переменную в такое состояние.

+0

При разработке вы можете в XCode включить настройку NSZombieEnabled. В некотором роде это создает экземпляры NSZombie во всех недопустимых местоположениях указателей, а NSZombie будет генерировать исключение или выдавать некоторые другие основные сообщения об ошибках для всех отправляемых им сообщений. См. Этот вопрос: http://stackoverflow.com/questions/535060/how-to-add-nsdebug-h-and-use-nszombie-in-iphone-sdk – harms

+0

Уточнение: NSZombieEnabled помогает отслеживать такие виды ошибок , но он не создает экземпляры NSZombie в «всех недопустимых местоположениях указателей». Он превращает объекты dealloc' в NSZombies вместо фактического освобождения их. Вы по-прежнему не получите исключений для зомби, если указатель установлен на адрес, который никогда не был объектом, например, примеры строк int или C, упомянутые в моем ответе. – Chuck

+0

Конечно, есть. Для моих целей «действительный объект» означает «экземпляр объекта». Вы можете использовать [obj isKindOfClass: [класс ObjClass]], и если он равен нулю, это будет false. Я просто подумал, что может быть ярлык с obj! = Nil. В моем случае, я знаю, что переменная всегда будет либо неинициализирована, нил, либо экземпляр класса X. – DougW