Является ли (переменная) такой же, как если бы (variable!= Nil) в Objective-C

Я получаю EXC_BAD_ACCESS (SIGBUS) в этой строке в моем проекте iPhone:

if (timeoutTimer) [timeoutTimer invalidate];

То, что меня озадачило, заключается в том, что я не понимаю, как эта строка может потерпеть крах, поскольку инструкция if предназначена для проверки на nil. Я не понимаю, как работает Objective-C, или номера строк в операторах сбоя когда-то имеют неправильную строку?

Ответ 1

Просто потому, что для переменной задано значение, отличное от nil, это не значит, что оно указывает на действительный объект. Например:

id object = [[NSObject alloc] init];
[object release];
NSLog(@"%@", object); // Not nil, but a deallocated object,
                      // meaning a likely crash

Ваш таймер, вероятно, уже был освобожден (или, возможно, вообще не был создан?), но переменная не была установлена ​​на нуль.

Ответ 2

Я просто столкнулся с подобной проблемой, так что вот еще один пример того, что может привести к сбою проверки, такой как ваш.

В моем случае я получал значение из словаря следующим образом:

NSString *text = [dict objectForKey:@"text"];

Впоследствии я использовал переменную следующим образом:

if (text) {
    // do something with "text"
}

Это привело к ошибке EXC_BAD_ACCESS и сбою программы.

Проблема заключалась в том, что в моем словаре использовались значения NSNull в тех случаях, когда объект имел пустое значение (он был десериализован из JSON), так как NSDictionary не может хранить значения nil. Я закончил работу над этим следующим образом:

NSString *text = [dict objectForKey:@"text"];
if ([[NSNull null] isEqual:text]) {
    text = nil;
}

Ответ 3

Они должны быть одинаковыми. Возможно, номер строки на самом деле неверен.

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