nil
действительно (void *)0
. NSNull
- это класс, который имеет один экземпляр, который вы можете получить с помощью [NSNull null]
. Юридически и безвредно отправлять сообщения в ноль, но нуль обмена сообщениями подвергается проверке типа времени выполнения.
Так что давайте инициализируем массив объекту NSNull. Любой код, который начинается этим путем, несомненно, вызывает печаль во время выполнения, но это именно то, что происходит, когда вы десериализация JSON (он должен сделать что-то с нулями, найденных в формате JSON) ...
NSArray *array = (NSArray *)[NSNull null]; // evil cast, just to illustrate
if (array == 0)
NSLog(@"I will never execute");
else
NSLog(@"I will always execute. null is a pointer to the instance of NSNull");
if ([array isKindOfClass:[NSNull class]]) // true, of course
if (array == [NSNull null]) // true, null is a singleton
if (!array) // false, same as above
if (array == nil) // false, same as above, array points to an object
NSLog(@"CRASH on next line, because null doesn't respond to count");
if (array.count > 0) // crash
Но если мы пробуем некоторые вещи, начиная с более доброкачественной nil
...
NSArray *array = nil;
// or NSArray *array; same thing, since compiler will init to 0x0 for you
if (array == 0)
NSLog(@"I will always execute");
else
NSLog(@"I will never execute");
if (!array) // true, same as above
if (array == nil) // true, of course
NSLog(@"No crash on next line");
if (array.count > 0)
NSLog(@"I will never execute");
это последний бит интересно. Мы можем отправить сообщение count в массив nil без штрафа. Он отвечает 0, как будто массив пуст. Что действительно происходит, так это то, что мы можем отправить любое сообщение в nil, и результат всегда будет равен нулю.
А что делать с вашей проблемой? Одна из идей - принять, что self.array иногда может быть == [NSNull null]
(что опять же не совпадает с == nil
). Лучшее решение состоит в том, чтобы поймать состояние JSON-NSNull в точке назначения, например ...
// I just finished deserializing some JSON to id someObject
self.someArray = (someObject.theArray == [NSNull null])? nil : someObject.theArray;
// anytime after, we can safely message the array
NSInteger theCount = self.someArray.count; // zero, if someArray is empty OR nil
// and even get objects from it, as long as it contains any
id someObject = (self.someArray.count)? [someArray lastObject] : nil;
Проверьте, что вы написали. «If» и «:» делают то же самое, поэтому что-то изменилось, когда вы изменили свой код. То, что вы описали, абсолютно невозможно на 100% с тем же self.someArray. – gnasher729