Если вы привыкли к Java, это может показаться странным. Вы ожидаете, что сообщение о создании объекта вызовет исключение при сбое, а не вернет nil
. Однако, хотя Objective-C в Mac OS X имеет поддержку обработки исключений ; это дополнительная функция, которую можно включить / выключить с помощью флага компилятора. Стандартные библиотеки написаны так, что их можно использовать без включенной обработки исключений: поэтому сообщения часто возвращают nil
, чтобы указать на ошибки, а иногда требуют, чтобы вы также передали указатель на переменную NSError*
. (Это для разработки на Mac, я не уверен, сможете ли вы даже включить поддержку обработки исключений для iOS, учитывая, что вы также не можете включить сборку мусора для iOS.)
В разделе «Обработка ошибок инициализации» в документе «Язык программирования Objective-C» объясняется, как программисты Objective-C должны исправлять ошибки при инициализации / создании объекта: то есть возвращать nil
.
Что-то вроде [NSData dataWithContentsOfFile: path]
может определенно возвращать nil
: документация по методу прямо говорит об этом. Но я, честно говоря, не уверен, вернется ли когда-нибудь что-то вроде [NSMutableArray arrayWithCapacity: n]
nil
. Единственная ситуация, которую я могу вспомнить, когда может , - это когда у приложения недостаточно памяти. Но в этом случае я ожидаю, что приложение будет прервано при попытке выделить больше памяти. Я не проверял это, хотя, и вполне может быть, что он возвращает nil
в этом случае. Хотя в Objective-C вы часто можете безопасно отправлять сообщения на nil
, это может привести к нежелательным результатам. Например, ваше приложение может попытаться создать NSMutableArray
, получить вместо него nil
, а затем успешно продолжить отправку addObject:
в nil
и записать пустой файл на диск, а не файл с элементами массива, как предполагалось , Поэтому в некоторых случаях лучше явно проверить, был ли результат сообщения nil
. Нужно ли делать это в каждом создании объекта, как это делает программист, которого вы цитируете, я не уверен. Лучше быть в безопасности, чем потом сожалеть?
Редактировать: Я бы хотел добавить, что хотя проверка успешности создания объекта иногда может быть хорошей идеей, утверждение может быть не лучшим идея. Вы бы хотели, чтобы это также проверялось в выпускной версии вашего приложения, а не только в отладочной версии. В противном случае это как бы лишает смысла проверять его, поскольку вы не хотите, чтобы конечный пользователь приложения, например, запустил пустые файлы, потому что [NSMutableArray arrayWithCapacity: n]
вернул nil
, и приложение продолжало отправлять сообщения на nil
возвращаемое значение Утверждения (с assert
или NSAssert
) могут быть удалены из версии выпуска с флагами компилятора; Xcode, по-видимому, по умолчанию не включает эти флаги в конфигурацию «Release». Но если вы захотите использовать эти флаги для удаления некоторых других утверждений, вы также удалите все проверки «Создание объекта успешно завершено».
Редактировать: После дальнейших размышлений кажется более правдоподобным, чем я думал, что [NSMutableArray arrayWithCapacity: n]
вернет nil
, а не прервет приложение, если недостаточно памяти. Basic C malloc
также не прерывается, но возвращает указатель NULL
, когда недостаточно памяти. Но я еще не нашел четкого упоминания об этом в документации Objective-C по alloc
и аналогичным методам.
Редактировать: Выше я сказал, что не уверен, что проверка nil
необходима при каждом создании объекта.Но так не должно быть.Именно поэтому Objective-C позволяет отправлять сообщения на nil
, которые затем возвращают nil
(или 0
или что-то подобное, в зависимости от определения сообщения): таким образом, nil
может распространяться через ваш код, несколько похожийисключение, чтобы не приходилось явно проверять наличие nil
в каждом отдельном сообщении, которое может его вернуть.Но рекомендуется проверять его в тех местах, где вы не хотите, чтобы он распространялся, например, при записи файлов, взаимодействии с пользователем и т. Д. Или в случаях, когда результат отправки сообщения на nil
не определен(как объяснено в документации по отправке сообщений на nil
).Я был бы склонен сказать, что это похоже на версию распространения и обработки исключений для «бедняков», хотя не все могут согласиться с тем, что последнее лучше;но nil
ничего не говорит вам о том, почему произошла ошибка, и вы можете легко забыть проверить ее там, где такие проверки необходимы.