Разница между nil, NIL и, null в Objective-C

#objective-c #null #nsnull

#objective-c #null #nsnull

Вопрос:

Я хочу знать разницу между nil , NIL и null . Я поискал в Google и нашел это:

nil -> нулевой указатель на объект Objective-C

NIL -> нулевой указатель на класс Objective-C

null -> нулевой указатель на примитивный тип или отсутствие данных

Но я не в состоянии четко понять термины «объект Objective-C» и «класс».

Пожалуйста, объясните мне это. Кроме того, есть ли в Objective-C какое-либо слово, подобное NSNull or NSNil ? Если да, то, пожалуйста, объясните, для чего это.

Комментарии:

1. Объект Objective-C является экземпляром класса Objective-C (того, который объявлен через @interface). Экземпляр обычно создается с помощью [[MyClass alloc] init] или [MyClass new].

2. В ObjC разница между объектом и классом такая же, как и в любом другом языке. Если вы этого не знаете — вам следует изучить основы ООП.

Ответ №1:

nil является буквальным значением null для объектов Objective-C, соответствующим абстрактному типу id или любому типу Objective-C, объявленному через @interface . Например:

 NSString *someString = nil;
NSURL *someURL = nil;
id someObject = nil;

if (anotherObject == nil) // do something
  

Nil является буквальным значением null для классов Objective-C, соответствующим типу Class . Поскольку большинству кода не нужны переменные для ссылки на классы, его использование не распространено. Одним из примеров является:

 Class someClass = Nil;
Class anotherClass = [NSString class];
  

NULL является буквальным значением null для произвольных указателей C. Например,

 int *pointerToInt = NULL;
char *pointerToChar = NULL;
struct TreeNode *rootNode = NULL;
  

NSNull это класс для объектов, которые представляют null. На самом деле, существует только один объект, а именно тот, который возвращается [NSNull null] . Это отличается от, nil потому что nil является буквальным значением null, т. Е. это не объект. С другой стороны, единственный экземпляр NSNull является надлежащим объектом.

NSNull часто используется в коллекциях Foundation, поскольку они не могут хранить nil значения. В случае словарей -objectForKey: возвращает nil значение, указывающее, что у данного ключа нет соответствующего объекта в словаре, т. е. ключ не был добавлен в словарь. Если вы хотите явно указать, что у вас есть определенный ключ, но у него еще нет значения, вы можете использовать [NSNull null] .

Например, следующее генерирует исключение, поскольку словари не могут хранить nil значения:

 NSMutableDictionary *dict = [NSMutableDictionary dictionary];
[dict setObject:nil forKey:@"someKey"];
  

С другой стороны, следующий код допустим, поскольку [NSNull null] не является nil объектом:

 NSMutableDictionary *dict = [NSMutableDictionary dictionary];
[dict setObject:[NSNull null] forKey:@"someKey"];
  

Стоит упомянуть, что коллекции Foundation имеют инициализаторы, которые используют nil в качестве маркера конец списка объектов без необходимости указывать количество элементов в списке. Это может произойти только потому, что nil не может быть сохранено в коллекции Foundation. Например,

 NSArray *array = [NSArray arrayWithObjects:@"one", @"two", nil];
  

Что касается NIL или NSNil , в Objective-C или Apple Foundation таких вещей нет.

Комментарии:

1. Вы также должны отметить, что можно отправлять сообщения на nil без ошибок сегментации.

2. спасибо за хорошее объяснение. но я хотел бы спросить, можем ли мы использовать NULL для объектов objective C?? как—> id myObj = NULL??

3. Это может быть отражено в swift? Например, есть ли в swift соответствие для этого?

Ответ №2:

Я не уверен, но я думаю, что nil следует использовать только вместо id , то, что программисты Java и C назвали бы pointer для object an. Используется NULL для указателей, не являющихся объектами.

nil обычно используется для типа объекта Objective-C, в то время как NULL используется для указателей в стиле c

Комментарии:

1. Это правильно. Я думаю, что на практике на самом деле не имеет значения, что вы используете. Но следуйте соглашению.

2. Соглашение полезно, но полезно знать, что nil , NULL и Nil — это одно и то же для компилятора.

Ответ №3:

Nil, Null и nil используются со следующими

1> Nil для класса Objective c

2> nil для объекта Objective c

3> Null для указателя C

Пример:

1> Класс A=Nil;

2>NSString strName=nil;

3> символ *pointerChar = NULL;

Комментарии:

1. элегантный пример, приятель

Ответ №4:

Предположим, у вас есть класс, MyClass который по соглашению nil используется, если вы хотите инициализировать его экземпляр значением null (таким же, как null в Java), т.е.

 MyClass *obj = nil;
  

и если вы хотите инициализировать примитивный указатель на нулевое значение (такое же, как в c), вы используете

 int *ptr = NULL; 
  

и если вы хотите инициализировать Class ссылкой на нулевое значение (такое же, как null в java), тогда используйте

 Class classRefOfMyClass = Nil;
  

Это просто соглашение, в противном случае Nil или nil имеют одинаковое значение и, возможно, NULL , nil или Nil все одинаковы.

Вот определение для них в objc.h файле

 #ifndef Nil
# if __has_feature(cxx_nullptr)
#   define Nil nullptr
# else
#   define Nil __DARWIN_NULL
# endif
#endif

#ifndef nil
# if __has_feature(cxx_nullptr)
#   define nil nullptr
# else
#   define nil __DARWIN_NULL
# endif
#endif
  

И в stddef.h

 #define NULL ((void*)0)
  

И определение __DARWIN_NULL в _types.h

 #define __DARWIN_NULL ((void *)0)
  

Таким образом, логически разницы нет. Основная идея здесь заключается в инициализации указателя, C или Objective-C на 0 . Если у вас есть знания о C , то вы можете назначить

 int *ptr = 0;
  

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

Короче говоря, все они являются 0 и ничем иным.

Комментарии:

1. В Java NULL используется нижний регистр: null

Ответ №5:

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

Все три из этих значений представляют null, или нулевой указатель, значения. Разница в том, что, хотя NULL представляет ноль для любого указателя, nil специфичен для объектов (например, id), а Nil специфичен для указателей классов.Следует считать своего рода наилучшей практикой использование правильного нулевого объекта в правильных обстоятельствах для целей документации, даже если ничто не мешает кому-либо смешивать и сопоставлять по ходу работы.

Приведенная ниже ссылка может вам каким-то образом помочь:

http://nshipster.com/nil/

Вот некоторая важная часть из ссылки:

введите описание изображения здесь

Ответ №6:

nil, NIL и null. зависит от вашего требования.

NSNull

коллекции, подобные NSArray и NSDictionary , не могут содержать нулевые значения.

 NSMutableDictionary *MymutableDictionary = [NSMutableDictionary dictionary];
MymutableDictionary[@"someKey"] = [NSNull null]; // Sets value of NSNull singleton for "someKey"
NSLog(@"Keys: %@", [mutableDictionary allKeys]);
  

ноль

все указатели, которые этот объект имеет на другие объекты, начинаются с nil , поэтому нет необходимости, например, устанавливать self.(association) = nil в методах инициализации.

На других языках, таких как C , это привело бы к сбою вашей программы, но в Objective-C вызов метода при nil возвращает нулевое значение.

 if (name != nil)
{
........
}
  

Значение символьного значения

nil (id)0 буквальное нулевое значение для объектов Objective-C

Nil (Class)0 буквальное нулевое значение для классов Objective-C