Коли я повинен використовувати 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.