Когда я должен использовать ноль и NULL в Objective-C?

170

Это пример кода:

NSDictionary *myDictionary = [NSDictionary dictionary];
NSNumber *myNumber = [myDictionary valueForKey: @"MyNumber"];
NSLog(@"myNumber = %@", myNumber); // output myNumber = (null)

if (myNumber == nil)
    NSLog(@"test 1 myNumber == nil");

if (myNumber == NULL)
    NSLog(@"test 2 myNumber == NULL");

if ([myNumber isEqual:[NSNull null]])
    NSLog(@"test 3 myNumber == [NSNull null]");

Когда мне следует использовать nil, NULL и [NSNull null]?

Биранчи
источник
4
Это связано с задачей С.
Биранчи
nilозначает вид NULLдля объекта. Таким образом, вы можете отметить конкретное значение, предназначенное для экземпляра объекта или общего указателя. С точки зрения управления типами и безопасности, это вам очень поможет.
eonil
4
nilи null/ NULLодинаковы - оба определены как ноль. В качестве формальности используйте nilпри кодировании Objective-C и NULLпри кодировании обычных операторов / вызовов C / C ++. NSNullоднако это нечто совершенно другое. Это одноэлементный объект, который служит заполнителем для представления «ничего», например, в NSDictionarys, где указатели nil / null недопустимы.
Hot Licks
Ссылка для хорошего объяснения [здесь] [1] [1]: stackoverflow.com/questions/5908936/…
Ameer
1
возможный дубликат NULL против nil в Objective-C
awiebe

Ответы:

114

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

В общем, просто используйте nil.

Alex
источник
12
технически они абсолютно равны, вы можете отправлять сообщения как на ноль, так и на NULL. Идиоматически, хотя nil обычно используется для представления объекта
коббал
41
также в MacTypes.h есть#define nil NULL
коббал
8
Да, как говорит Коббал, они одинаковы. Это скорее контекстная ссылка, где NULL - указатель на 0x0, nil - несуществующий объект target-c, а Nil - несуществующий класс target-c, но технически все они равны 0. Кроме того, это NULL не нуль - ноль в Java или C #, но не в Objective-C.
Джейсон Коко
16
Этот принятый ответ не признает, что [NSNull null]это совсем другой зверь. Процитируем из ссылки на класс NSNull: «Класс NSNull определяет одноэлементный объект, используемый для представления нулевых значений в объектах коллекции (которые не допускают нулевые значения)». Также см. Раздел « Использование NSNull» в разделе « Программирование чисел и значений».
Роб
«Главное отличие в том, что вы можете отправлять сообщения на ноль» - вы можете отправлять сообщения и на NULL.
313

Они различаются по своим типам. Все они равны нулю, но NULLявляются void *, nilявляются idи Nilявляются указателями класса.

оборота NSResponder
источник
14
Лучшее объяснение, которое я слышал о разнице (: Спасибо.
Джейкоб
3
Это должен быть принятый ответ не потому, что за него проголосовало больше, а потому, что он дает лучшее объяснение поставленному вопросу.
Джеймс Мерц
5
Элегантное описание NULLv nil, но это серьезно не попадает в цель [NSNull null]. См. Раздел « Использование NSNull» разделов « Программирование чисел и значений» и « Справочник по классам NSNull» .
Роб
Оба, кажется, указатели на void *. Другой ответ здесь уже упоминает об этом, но если вы покопаетесь objc.h, вы найдете строку #define nill __DARWIN_NULL.
gkb0986
1
Этот ответ звучит хорошо, но согласно другим ответам он просто неверен.
13
30

nil - это пустое значение, связанное / соответствующее объекту (тип id в Objective-C). У nil нет ссылки / адреса, просто пустое значение.

NSString *str = nil;

Поэтому следует использовать ноль, если мы имеем дело с объектом.

if(str==nil)
    NSLog("str is empty");

Теперь NULL используется для необъектного указателя (например, указателя C) в Objective-C. Как и ноль , NULL не имеет ни значения, ни адреса.

char *myChar = NULL;
struct MyStruct *dStruct = NULL;

Поэтому, если есть ситуация, когда мне нужно проверить, что моя структура (переменная типа структуры) пуста или нет, я буду использовать:

if (dStruct == NULL)
    NSLog("The struct is empty");

Давайте еще один пример,

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context

Для наблюдения значения ключа контекст должен быть указателем C или ссылкой на объект. Здесь для контекста мы не можем использовать ноль ; мы должны использовать NULL .

Наконец, класс NSNull определяет одноэлементный объект, используемый для представления нулевых значений в объектах коллекции (NSArray, NSDictionary). [NSNull нуль] Воля возвращает синглтон Экземпляр NSNull. В основном [NSNull null] является правильным объектом.

Нет способа вставить объект nil в объект типа коллекции. Давайте приведем пример:

NSMutableArray *check = [[NSMutableArray alloc] init];
[check addObject:[NSNull null]];
[check addObject:nil];

Во второй строке мы не получим никакой ошибки, потому что совершенно справедливо вставить объект NSNull в объект типа коллекции. В третьей строке мы получим ошибку «объект не может быть нулем». Потому что ноль не является объектом.

Шад
источник
+1 за упоминание о практическом использовании nil / null в массиве.
Майкл
19

NULL и nil равны друг другу, но nil - это значение объекта, в то время как NULL - это общее значение указателя ( (void*)0если быть точным). [NSNull null]это объект, который должен заменять ноль в ситуациях, когда ноль не разрешен. Например, вы не можете иметь значение nil в NSArray. Так что если вам нужно представить «ноль», вы можете использовать [NSNull null].

Chuck
источник
12

Я нашел следующее:

objc.h

#define Nil __DARWIN_NULL   /* id of Nil class */
#define nil __DARWIN_NULL   /* id of Nil instance */

_types.h

#define __DARWIN_NULL ((void *)0)

stddef.h

#undef NULL
#ifdef __cplusplus
#undef __null  // VC++ hack.
#define NULL __null
#else
#define NULL ((void*)0)
#endif

MacTypes.h

#ifndef NULL
#define NULL    __DARWIN_NULL
#endif /* ! NULL */
#ifndef nil
    #define nil NULL
#endif /* ! nil */

Как это выглядит, нет никакой разницы, кроме концептуальной.

Colnaghi
источник
8

Остерегайтесь того, что if([NSNull null])возвращается true.

Николас Манзини
источник
7

Они оба - только ноль. Функционально между ними нет разницы. то есть.,

#define NULL ((void*)0)
#define nil ((id)0)

Есть разница, но только для вас и других людей, которые читают код, компилятору все равно.

Еще одна вещь, nil - это значение объекта, а NULL - это общее значение указателя.

Nirav
источник
6

В современных OS X и iOS SDK:

  • nilи Nilи NULLидентичны в Objective-C и в Objective-C ++ до C ++ 11.
  • nilи Nilи std::nullptrидентичны в Objective-C ++ с C ++ 11.

Стилистически, многие люди предпочитают использовать nilдля объектов Objective-C и NULLили nullptrдля других типов указателей. Я сам сейчас пользуюсь nilвезде.

[NSNull null]является одноэлементным объектом, используемым для представления нулевых значений в ситуациях, когда nilэто запрещено как значение (обычно в объекте коллекции, например, NSArrayили NSDictionary) Темы программирования чисел и значений: использование NSNull

Грег Паркер
источник
5

Чтобы расширить комментарий от @cobbal:

MacTypes.h содержит:

#ifndef nil
   #define nil NULL
#endif
Джастин Таннер
источник
4

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

Для всего, что связано с Objective-C, я использую ноль. Например:

- (BOOL)doSomethingWithObjectsInArray:(NSArray *)anArray {
    if (anArray == nil) return NO;

    // process elements
    ...
}

Однако при проверке достоверности моделей данных из C-фреймворка (например, фреймворка AddressBook и CoreFoundation) я использую NULL. Например:

- (BOOL)showABUnknownPersonVCForABRecordRef:(ABRecordRef)aRecord {
    if (aRecord == NULL) return NO;

    // set-up the ABUnknownPersonViewController and display it on screen
    ..
}

Таким образом, у меня есть тонкие подсказки в моем коде, если я имею дело с кодом на основе Obj-C или C.

оборота Тафкадасох
источник
4

nil - это указатель на объект. Хотя они семантически отличаются от NULL , они технически эквивалентны друг другу.

На уровне структуры Foundation определяет NSNull , который определяет метод класса + null, который возвращает одноэлементный объект NSNull. NSNull отличается от nil или NULL тем , что это фактический объект , а не нулевое значение.

Кроме того, в Foundation / NSObjCRuntime.h Nil определяется как указатель класса на ничто.

См. Это для получения дополнительной информации - ноль / ноль / NULL / NSNull

Шубхам Джайн
источник
3

В некоторых контекстах есть разница.

Буквально, Null - это персонаж: ASCII 0.

Ноль эквивалентно пустому, нет значения.

В зависимости от контекста программирования, это может быть большой разницей.

мясной рулет
источник
1

Например, используйте NULL при вызове метода Objective-C с выходным параметром типа (NSError **).

Я вижу много примеров кода в Интернете, где люди предоставляют nil вместо NULL в этом случае. Это потому, что это указатель на указатель и, следовательно, не напрямую объектный тип Objective-C. Как сказано выше, nil следует использовать для типов объектов Objective-C.

Peter Mortensen
источник
1

В основном: nil: нулевой указатель на объект и null: для другого указателя типа

gerachev
источник
0

nil означает отсутствие значения, в то время как NULL представляет No Object,

NSArray * array = @ [@ "Hello World!", @ 101, [NSNULL null]];

Здесь [NSNULL null] является объектом, который означает отсутствие объекта, в то же время вы не можете добавить nil, чтобы указать на отсутствие объекта.

Вы также можете использовать как nil, так и [NSNUll null] для проверки.

Рошан Сах
источник
0

Это поможет вам понять разницу между нулем, нулем и нулем.

Ссылка ниже может помочь вам в некотором роде:

http://nshipster.com/nil/

nil -> буквальное нулевое значение для объектов Objective-C.

Nil -> буквальное нулевое значение для классов Objective-C.

NULL -> буквальное нулевое значение для указателей Си.

NSNULL -> одноэлементный объект, используемый для представления нуля.

Субхакар Прабху
источник
это добавляет что-то новое (что не охватывается существующими ответами)?
Флориан Кох