Что лучше всего описывает ноль? Что это на самом деле? - PullRequest
13 голосов
/ 03 декабря 2009

В настоящее время я понимаю это как некий «пустой объект». Но что это на самом деле?

Ответы [ 9 ]

33 голосов
/ 04 декабря 2009

Объекты Objective-C

Прежде всего, когда вы называете это:

id someObject = [NSArray array];

someObject не является объектом массива напрямую, а только указателем на него. Это означает, что если someObject равно 0x1234, то в памяти есть объект по этому адресу.

Вот причина, по которой

id someOtherObject = someObject;

не копирует объект. Оба указателя теперь указывают на один и тот же объект.

Указатель на 0x0

Итак, как определяется nil? Давайте посмотрим на исходный код:

objc.h

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

_types.h

#ifdef __cplusplus
…
#else /* ! __cplusplus */
#define __DARWIN_NULL ((void *)0)
#endif /* __cplusplus */

Похоже, nil это указатель на адрес 0x0.

И что?

Давайте посмотрим, что может сказать Справочник по программированию Objective-C :

Отправка сообщений на ноль

В Objective-C допустимо отправлять сообщение на ноль - оно просто не имеет никакого эффекта во время выполнения. Есть несколько моделей в какао, которые пользуются этим факт. Значение, возвращаемое из сообщение на ноль также может быть действительным:…

Возвращаемые значения: nil, 0 или struct со всеми переменными, инициализированными равными 0. Какая из них зависит от ожидаемого типа возвращаемого значения. Существует явная проверка во время выполнения target-c для сообщений на nil, это означает, что это действительно быстро.

Nil, nil, NULL

Это 3 типа. Вот все определения:

#define Nil __DARWIN_NULL   /* id of Nil class */
#define nil __DARWIN_NULL   /* id of Nil instance */
#define NULL __DARWIN_NULL
#define __DARWIN_NULL ((void *)0)

Как видно, все они абсолютно одинаковы. Nil и nil определены Objective-C, NULL происходит от C.

Какая тогда разница? Это только о стиле. Это делает код более читабельным.

  • Nil используется как несуществующий класс: Class someClass = Nil.
  • nil используется как несуществующий экземпляр: id someInstance = nil.
  • NULL - указатель на несуществующую часть памяти: char *theString = NULL.

Short

nil не пустой объект, а несуществующий. Метод -getSomeObject не возвращает пустой объект, если он не существует, но возвращает nil, который сообщает пользователю об отсутствии объекта.

Может быть, это имеет смысл: (И то и другое скомпилируется и запустится.)

if (anObject == nil) {   // One cannot compare nothing to nothing,
                         // that wouldn't make sense.

if (anObject) {          // Correct, one checks for the existence of anObject
14 голосов
/ 03 декабря 2009

Это не пустой объект, это отсутствие какого-либо объекта вообще. Остальные ответы охватывают другую семантику, поэтому я оставлю это на этом:)

7 голосов
/ 03 декабря 2009

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

NSString *myString = nil; // myString points to nothing
int x = nil; // invalid, "x" is not a pointer, but it will compile
3 голосов
/ 03 декабря 2009

Это нулевой указатель - указатель на "ничто".

3 голосов
/ 03 декабря 2009

Это "ничего". Но «ничто», на которое вы можете отправлять сообщения, не будучи убитым, как если бы вы пытались вызвать метод на NULL.

Вы можете посмотреть этот вопрос, чтобы получить больше информации о NULL против nil

1 голос
/ 03 декабря 2009

Один полезный способ думать о nil - представить, что это пустой объект, который «ничего не делает».

Под словом "ничего не делает" я имею в виду, что любое отправленное вами сообщение не будет иметь побочных эффектов.

Он "пустой" в том смысле, что когда вы запрашиваете у него значение какого-либо свойства, он всегда возвращает nil. Таким образом, он не содержит никаких значений -> он пустой.
(На самом деле, это немного сложнее, чем когда вы запрашиваете значение свойства, которое возвращает тип, который НЕ является объектом obj-c. Вы получите обратно указатель размером 0. Поэтому для любых скалярных значений, которые не больше sizeof(void*), вы получите 0. Но если вы попросите struct или double в 32-битной системе, вы получите неопределенный результат . Я написал о это здесь .)

1 голос
/ 03 декабря 2009

Формально определено, как определено Джошуалом - указатель на ничто или указатель на объект вообще.

С практической точки зрения реализации, особенно при работе со структурами данных и алгоритмами, ноль часто будет представлять часового в структуре данных или объект, который представляет «ничто», например, в красно-черном дереве, технически, все конечные узлы имеют «ноль», но они по-прежнему имеют одинаковые или похожие свойства и операции конечного узла (цвет, указатель на родительский узел и т. д.) - в этих случаях это действительно «ничего». .. если это имеет смысл.

Итак, формально, это указатель на ничто, на практике его часто рассматривают как представление ничто, но это никогда не ... ноль.

0 голосов
/ 03 декабря 2009

Просто чтобы уточнить, в Objective-C ноль и ноль - это не одно и то же. Они также не представляют в Objective-C то же самое, что они делают в математике или других языках программирования.

Nil на самом деле является специальным адресом памяти 0x0 (по крайней мере, компилятор обрабатывает его как адрес.) Nil используется как адрес объекта, который назван, но не выделен. Это позволяет проверить наличие / распределение именованных объектов, а также обеспечить безопасный способ отправки сообщений объектам, которые могут не существовать. В то время как в математике и некоторых языках вы можете сравнивать скалярные переменные с nil, в Objective-c вы не должны. Вы должны только сравнить адреса объектов.

NULL, напротив, может означать либо стандартный C, определенный как целочисленное значение NULL==0, либо он может представлять фактический выделенный объект класса NSNull с конкретным адресом в памяти. NSNull, однако, является одноэлементным объектом, то есть только один существует для каждого приложения. Он используется в качестве заполнителя для других объектов, обычно в коллекциях. Вы не можете использовать его в сравнении с любым другим объектом. Вы можете только проверить, указывает ли конкретный указатель на одноэлементный объект NSNull. Обратите внимание, что в качестве выделенного объекта [NSNull null]!=NULL,

Путаница между nil и NULL возникает потому, что присвоение адреса NULL присваивает его нулевому адресу 0x0. Такой код работает, но иногда может вызвать тонкую проблему. Лучше всего привыкнуть не путать их.

Итак, в Objective-C nil, NUll и NSNull - это три разных, но частично совпадающих понятия, которые легко перепутать. Nil должен использоваться для адресов, NULL должен использоваться для скалярных значений, а NSNull должен использоваться в качестве заполнителя для выделенных объектов.

0 голосов
/ 03 декабря 2009

Может быть, я просто упускаю очевидное, но это похоже на смысловой вопрос. Например, вы можете использовать множество разных слов для его описания, но ваше описание уже работает достаточно хорошо.

http://en.wikipedia.org/wiki/Null_(computer_programming)

...