Коли я повинен використовувати nil та 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для об'єкта objc. Таким чином, ви можете позначити конкретне значення, призначене для екземпляра objc або загального вказівника. Зважаючи на управління типом та безпеку, це вам дуже допоможе.
eonil

4
nilта null/ NULLє однаковими - обидва визначені як нульові. В якості формальності використовуйте nilпри кодуванні Objective-C та NULLпри кодуванні регулярних C / C ++ операторів / викликів. NSNullце щось зовсім інше. Це однотонний об'єкт, який виконує функції "місця" для відображення "нічого", наприклад, NSDictionarys, де покажчики нуля / нуль не дозволені.
Гарячі лизання

Перейдіть за посиланням для хорошого пояснення [тут] [1] [1]: stackoverflow.com/questions/5908936/…
Ameer

1
можливий дублікат NULL проти нуля в Objective-C
awiebe

Відповіді:


114

Ви можете користуватися nilде завгодно null. Основна відмінність полягає в тому, що ви можете надсилати повідомлення nil, тому ви можете використовувати їх у деяких місцях, де nullне можна працювати.

Взагалі просто використовувати nil.


12
технічно вони точно рівні, ви можете надсилати повідомлення і на нуль, і на NULL. Ідіоматично, хоча нуль зазвичай використовується для представлення об'єкта
кобаль

41
також, у MacTypes.h є#define nil NULL
кабал

8
Так, як кабал каже, вони однакові. Це скоріше контекстна посилання, де NULL є вказівником на 0x0, nil - неіснуючий об'єкт-c-об'єкта, а Nil - неіснуючий клас Obje-c, але технічно вони всі лише 0. Крім того, це NULL не null - null є в Java або C #, але не в Objective-C.
Джейсон Коко

16
Ця прийнята відповідь не визнає, що [NSNull null]це зовсім інший звір. Для цитування з NSNull Class Reference : "Клас NSNull визначає однотонний об'єкт, який використовується для представлення нульових значень в об'єктах колекції (які не дозволяють нульових значень)." Також див. Розділ Використання NSNull Теми програмування чисел та значень.
Роб

"Основна відмінність полягає в тому, що ви можете надсилати повідомлення до нуля" - ви також можете відправляти повідомлення NULL.

313

Вони відрізняються за своїми типами. Всі вони дорівнюють нулю, але NULLце - є void *, nilє idі Nilє вказівником класу.


14
Найкраще пояснення, що я чув про різницю (: Спасибі.
Яків

3
Це має бути прийнятою відповіддю не тому, що є більше голосів, а більше, тому що це найкраще пояснення поставленого питання.
Джеймс Мерц

5
Елегантний опис NULLv nil, але це серйозно пропускає позначку re [NSNull null]. Див. Розділ Використання NSNull розділу Теми програмування чисел та значень та довідник про клас NSNull .
Роб

Обидва, здається, є вказівниками на void *. Тут вже згадується інша відповідь, але якщо ви заглибитесь objc.h, ви знайдете рядок #define nill __DARWIN_NULL.
gkb0986

1
Ця відповідь звучить добре, але згідно з іншими відповідями вона просто неправильна.
n13,

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] є належним об'єктом.

Немає можливості вставити об'єкт нуля в об’єкт типу колекції. Наведемо приклад:

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]- це об'єкт, який покликаний стояти на нулі в ситуаціях, коли нуль заборонено. Наприклад, ви не можете мати значення нуля в NSArray. Тож якщо вам потрібно представити "нуль", ви можете використовувати [NSNull null].


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

У тому, як це виглядає, немає різниці, крім концептуальної.



7

Вони обоє - це просто набір нуля. Функціонально між ними немає різниці. тобто.,

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

Різниця є, але компілятор не хвилює лише себе та інших людей, які читають код.

Ще одна річ нуль - це об'єктне значення, тоді як NULL - це загальне значення вказівника.


6

У сучасних SDK для OS X та iOS:

  • 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



4

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

Для всього, що стосується Objective-C, я використовую нуль. Наприклад:

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

    // process elements
    ...
}

Однак, перевіряючи достовірність моделей даних із С-каркасу (наприклад, Framework 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 , вони технічно рівнозначні один одному.

На рамковому рівні Фонд визначає NSNull , який визначає метод класу, + null, який повертає однотонний NSNull об'єкт. NSNull відрізняється від нуля або NULL тим , що це фактичний об'єкт , а не нульове значення.

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

Перегляньте це для отримання додаткової інформації - nil / Nil / NULL / NSNull


3

У деяких контекстах є різниця.

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

Ніль еквівалентний порожньому, без значення.

Залежно від контексту програмування це може бути великою різницею.


1

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

Я бачу в Інтернеті безліч прикладних кодів, де люди надають нуль замість NULL в цьому випадку. Це тому, що це вказівник на покажчик і, отже, не є безпосередньо типом об’єкта Objective-C. Як було сказано вище, для типів об'єктів Objective-C слід використовувати нуль.


1

В основному: nil: null pointer на об’єкті і null: є для вказівника іншого типу


0

нуль означає відсутність значення, тоді як NULL не представляє об'єкт,

NSArray * array = @ [@ "Привіт, світ!", @ 101, [NSNULL null]];

Тут [NSNULL null] - це об'єкт, що означає відсутність об'єкта, в той же час ви не можете додати нуль, щоб вказати на відсутність об'єкта.

для перевірки також можна використовувати як nil, так і [NSNUll null].


0

Це допоможе вам зрозуміти різницю між нулем, NIL і null.

Нижче наведене посилання може вам допомогти певним чином:

http://nshipster.com/nil/

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

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

NULL -> буквальне нульове значення для C покажчиків.

NSNULL -> одиночний об'єкт, який використовується для представлення нуля.


чи додає це щось нове (що не стосується існуючих відповідей)?
Флоріан Кох
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.