Что должен делать этот (NSNull *) контроллер == [NSNull null]? Почему не просто контроллер == nil?

В примере Apple я видел это:

myController *controller = [viewControllers objectAtIndex:page];
if ((NSNull *)controller == [NSNull null]) {
    controller = [[myController alloc] initWithPageNumber:page];
    [viewControllers replaceObjectAtIndex:page withObject:controller];
    [controller release];
}

Меня очень интересует эта строка:

if ((NSNull *)controller == [NSNull null]) {

Если бы я сделал это, я бы просто проверил нуль. Почему они делают это так чертовски сложно? И что это на самом деле делает? Для меня это похоже на то, что они перебрасывают объект контроллера в NSNull, а затем проверяют, совпадает ли это с NNN.

A.F.A.I.K. nil означает "no object", а null означает "ничего". Пожалуйста, помогите мне получить четкую картину здесь!

Ответ 1

В большинстве контейнеров не допускается вставка объекта "nil". Если вы действительно хотите вставить нулевое значение в свой контейнер, можно использовать экземпляр NSNull (NSNull - одноэлементный).

В вашем конкретном примере контроллер извлекается из массива. Тогда хорошая практика - убедиться, что объект не является экземпляром NSNull.

Ответ 2

Коллекционные классы, такие как NSArray и NSDictionary, не могут содержать значения nil. Ваш ivar, viewController, является экземпляром класса коллекции. NSNULL был создан специально как placeholder для nil, и вы можете поместить его в классы коллекции.

Класс NSNULL определяет одноэлементный объект, а это означает, что существует только один экземпляр NSNULL (который вы создаете с помощью [NSNull null]), но он может использоваться как можно больше мест.