Является ли (obj && obj! = Nil) правильным и необходимым? - PullRequest
3 голосов
/ 18 ноября 2009

Две части к этому вопросу

1) Это понимание того, что происходит правильно?
«if (obj)» проверяет, не является ли указатель 0x0, то есть установлен в целочисленный адрес памяти
«if (obj! = nil)» сравнивает адрес памяти объекта с адресом памяти универсального объекта 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];
}

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

Ответы [ 5 ]

17 голосов
/ 18 ноября 2009

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

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

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

12 голосов
/ 18 ноября 2009

Это правильно, в том смысле, что оно даст вам ожидаемый результат, но излишне. Достаточно просто использовать:

if (obj) {

или

if (obj != nil) {
4 голосов
/ 18 ноября 2009

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

  • Мусорное пространство, где раньше находился освобожденный объект
  • Новый объект, который был размещен вместо объекта, на который должна указывать переменная
  • Int, который вы случайно установили для переменной
  • Строка C, для которой вы случайно установили переменную вместо NSString

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

4 голосов
/ 18 ноября 2009

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

0 голосов
/ 18 ноября 2009

if (obj == nil) тогда if (obj) будет оценивать false Вам не нужны оба.

...