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

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

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]?

16 ответов

Решение

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

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

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

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 null] возвращает одноэлементный экземпляр NSNull. В основном [NSNull null] является правильным объектом.

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

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

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

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

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

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 */

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

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

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

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

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

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

В современных 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

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

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

#ifndef nil
   #define nil NULL
#endif

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

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

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

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

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

Для всего, что связано с 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.

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

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

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

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

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

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

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

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

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

http://nshipster.com/nil/

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

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

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

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

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

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

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

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

Другие вопросы по тегам