Что означает «отправка сообщения на ноль» и почему это особый случай? [Дубликат]

This question already has an answer here:

Sending a message to nil in Objective-C 11 answers

Я только начал читать учебные пособия по Objective-C, и есть раздел, посвященный отправке сообщенияnil& Quot ;:

There are several patterns in Cocoa that take advantage of this fact. The value returned from a message to nil may also be valid:

Что это значит? Я не могу следовать этому.

Ответы на вопрос(4)

Что именно вы не понимаете в этих документах?

 02 июл. 2009 г., 17:10
@Marc: Все объекты оцениваются равными целому числу. Вы можете отправлять сообщения в nil (что верно для каждого объекта, а не для необъектов в Objective-C), так что, по крайней мере, концептуально nil можно осмысленно назвать объектом. Это особая ценность.
 02 июл. 2009 г., 16:12
& Quot; ноль & Quot; является нулевым объектом. Если вы "знакомы с Java", отправьте сообщение nil & quot; эквивалентно «вызову метода с нулевым значением»; в Java, за исключением того, что в Java вы получаете исключение NullPointerException, тогда как в Objective-C ничего не происходит. Таким образом, вы можете безопасно сделать что-то вроде & quot; [nil doThis: withThis] & quot; и программа не потерпит крах (метод просто вернет ноль).
 Blankman02 июл. 2009 г., 15:41
что такое ноль? Вы передаете значение null в метод объекта? или отправка значения null в сообщение? что за сообщение?
 02 июл. 2009 г., 17:04
Не совсем. Ноль равен 0, это не объект. Вот почему вы можете сделать то же самое с методами, которые возвращают целочисленное значение. Существует специальный объект NSNull, который вы можете использовать в классах коллекций, но он не равен nil.
 03 июл. 2009 г., 01:11
& Quot; ноль & Quot; обычно относится к нулевому экземпляру и «Nil»; обычно относится к нулевому классу. Я думаю, что во время выполнения GNU они на самом деле явно приводятся (id) 0 и (Class) 0, но в настоящее время я имею доступ только к средам выполнения NS. Предварительно 10.5 среды выполнения определили nil и Nil только 0, но 10.5 определяет их как __DARWIN_NULL.

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

id obj1 = [SomeClass object];
id obj2 = [obj1 doSomething];
id obj3 = [obj2 anotherMethod];

id thingICareAbout = [obj3 doSomethingElse];

Если вы пройдете несколько шагов, чтобы добраться доthingICareAbout, он сохраняет много ненужных строк кода, чтобы не проверять, равны ли значения obj1, obj2 и т. д. перед их использованием. Вы можете просто проверить, еслиthingICareAbout ноль один раз в конце, если вам нужно. Иногда вам даже не нужно этого делать, если ваш код все еще работает, когда он равен нулю (или 0 для примитивных значений).

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

Еще одна вещь, которую нужно иметь в виду (я только что узнал сам!), Это то, что 10.5 изменил это поведение - раньше было так, что он был безопасен только для целых чисел и указателей на объекты, а не на структуры или значения с плавающей запятой. Из-за этого вы можете увидеть дополнительную проверку ошибок при просмотре другого кода.

nil означает, что вы можете сделать следующее:

SomeClass * someObject;
someObject = nil;
[someObject doSomething];

И вы можете быть уверены, что ничего не произойдет.

Теперь, почему это важно?

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

[someObject updateRecords]; // 1
x = [someObject size];      // 2

Строка 1 отправляетsomeObject сообщение называетсяupdateRecordsи строка 2 отправляет тому же объекту сообщение с именемsize, который, как ожидается, вернет значение. Эти сообщения сводятся к вызовам методов, и фактический код, который в итоге запускается, определяется системой времени выполнения Objective C, поскольку Objective C является языком с динамической типизацией.

Чтобы определить, какой метод вызывать, система времени выполнения считывает информацию с адреса рассматриваемого объекта (someObjectв приведенных выше примерах), чтобы выяснить, к какому классу он относится. Используя эту информацию, он может найти соответствующий метод для вызова, а когда все выяснено, он выполняет код в методе.

Если система выполнения не лечилаnil как особый случай, он, вероятно, потерпит крах, если вы попытаетесь выполнить код, показанный сверху.nil определяется как ноль, поэтому среда выполнения будет начинать чтение информации с адреса, хранящегося в нуле в памяти, что почти гарантировано как нарушение прав доступа.

 28 июл. 2013 г., 18:28
Так почему вraywenderlich.com/2696/…говорят, что «отправка сообщения в освобожденную память вызывает сбой» ?
 30 июл. 2013 г., 01:56
Отправка сообщения в освобожденную память (также известную как зомби) может произойти, если вы отпустите объект, но при этом сохраните указатель на старую область памяти. Например:[someObject release]; [someObject someMethod];, Это очень отличается отsomeObject = nil; [someObject someMethod]; Даже если для параметра someObject установлено значение nil, это может привести к его освобождению в среде GC, но при установке значения nil вы также не сможете отправить сообщениеdeallocated объем памяти.
nil is basically a null pointer (i.e. it is the number zero stored in a pointer). All messages to nil are legal (they won't cause a crash), but they don't do anything. All messages to nil return nil, or 0, or 0.0, or NO, depending on the return type.
 03 июл. 2009 г., 01:04
Точка 3 зависит от времени выполнения. В более ранних версиях документации говорилось, что вы не можете полагаться на возвращаемое значение сообщения, равное nil, если возвращаемый метод с плавающей запятой, удваивает или превышает переменные размером с натуральное слово.

Ваш ответ на вопрос