Когда мне следует использовать nil в объекте-c?

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

Не уверен, полностью ли понял разницу. Я понял, что NULL следует использовать для указателей в стиле C и nil для указателей идентификаторов и объектов.

Я читал «Программирование на Objective-C, четвертое издание» Стивена Кочана. Некоторые примеры кода в книге противоречат тому, что было описано в вопросе выше.

Например:

Один пример кода создает метод, который возвращает NSMUtableArray, где он пытается заполнить NSMutableArray, если массив пуст, в конце он возвращает nil:

-(NSMutableArray *) someMethod
{
  NSMutableArray *arr = [NSMutableArray array];

  //try to populate arr

  if([arr count])
  {
    return arr;
  }
  else
  {
    return nil;
  }
}

Позже в другом примере кода он использует NULL для объекта-указателя.

{
   NSFileManager *fm = [NSFileManager defaultManager];
   [fm copyItemAtPath: @"some file path" error: NULL]
}

В документации NSFileManager говорится, что нужно передать nil для указателя NSError, если информация об ошибке не нужна. введите описание изображения  здесь

https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSFileManager_Class/index.html#//apple_ref/occ/instm/NSFileManager/copyItemAtPror:toPath:er/copyItemAtPror:toPath:er:


person Amre    schedule 22.11.2014    source источник
comment
Все объекты Objective-C используются как указатели, а не как значения. Таким образом, тип объекта всегда SomeType*. Причина, по которой в вашем примере используется NULL, заключается в том, что это двойной указатель, а не просто одиночный указатель. Другой способ думать об этом может заключаться в том, что вы обычно используете NULL там, где это может быть разыменовано, и nil там, где этого не будет.   -  person ahruss    schedule 22.11.2014


Ответы (2)


В приведенных вами примерах кода он используется правильно. NSMutableArray * - это тип указателя на объект Objective-C. Итак, мы используем nil. С другой стороны, второй параметр copyItemAtPath:toPath:error: имеет тип NSError **, который не является типом указателя объекта Objective-C. Это обычный указатель C на тип указателя NSError * (NSError * является типом указателя объекта Objective-C; однако указатель на него не является). Итак, мы используем NULL.

В основном это зависит от «указателя» на что. NSMutableArray * - это тип указателя на объект ObjC. С другой стороны, NSError ** - это тип указателя на указатель. Указатель на указатель, указатель на примитив и указатель на что-либо еще являются обычными указателями C. Обратите внимание, что в ARC управляются только типы указателей объектов Objective-C.

Что касается документации, я считаю, что это связано с добавлением Swift. До Swift в старой документации было указано NULL. В Swift различные типы указателей C также используют nil (который является общей константой, которая может быть значением любого типа, соответствующего NilLiteralConvertible) для нулевого указателя.

person newacct    schedule 22.11.2014

По сути, поскольку память теперь полностью управляется ARC, вы можете обойтись без использования любого или в своем коде. Однако nil предназначен для всех объектов Objective-C, например. NSError, а NULL - для таких вещей в стиле C, как (void *).

person Rob Sanders    schedule 22.11.2014