В Objective C, почему я должен проверить, не является ли сам = [супер init] нолем?

Единственный полезный спецификатор исключения является "броском ()", поскольку в "не бросает".

163
задан Jasarien 17 August 2009 в 13:25
поделиться

6 ответов

Например:

[[NSData alloc] initWithContentsOfFile:@"this/path/doesn't/exist/"];
[[NSImage alloc] initWithContentsOfFile:@"unsupportedFormat.sjt"];
[NSImage imageNamed:@"AnImageThatIsntInTheImageCache"];

... и так далее. (Примечание: NSData может вызвать исключение, если файл не существует). Есть довольно много областей, в которых возврат nil является ожидаемым поведением при возникновении проблемы, и из-за этого стандартная практика - почти все время проверять наличие nil для согласованности.

52
ответ дан 23 November 2019 в 21:20
поделиться

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

И да. к сведению, я следую лучшим практикам и пишу их во всех моих классах, даже в тех, которые являются производными непосредственно от NSObject .

7
ответ дан 23 November 2019 в 21:20
поделиться

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

2
ответ дан 23 November 2019 в 21:20
поделиться

Вы правы, вы часто можете просто написать [super init] , но это не сработает для подкласса чего угодно. Люди предпочитают просто запоминать одну стандартную строку кода и использовать ее все время, даже когда это необходимо лишь иногда, и поэтому мы получаем стандартный if (self = [super init]) , который требует как возможность возврата nil и возможность возврата объекта, отличного от self .

3
ответ дан 23 November 2019 в 21:20
поделиться

Эта конкретная идиома является стандартной, потому что она работает во всех случаях.

Хотя это и необычно, будут случаи, когда ...

[super init];

... возвращает другой экземпляр, таким образом требуя присваивание себе.

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

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

50
ответ дан 23 November 2019 в 21:20
поделиться

Это своего рода резюме комментариев выше.

Допустим, суперкласс возвращает nil. Что произойдет?

Если вы не будете следовать соглашениям

Ваш код рухнет в середине метода init. (если только init не делает ничего важного)

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

Ваш код, вероятно, упадет в какой-то момент позже, потому что ваш экземпляр nil, а вы ожидали чего-то другого. Или же ваша программа поведет себя неожиданно, но без сбоя. О, Боже! Хотите ли вы этого? Я не знаю...

Если вы следуете конвенциям, охотно позволяя своему подклассу возвращать nil

В вашей документации к коду(!) должно быть четко указано: "возвращает ... или nil", а остальная часть вашего кода должна быть подготовлена к работе с этим. Теперь это имеет смысл.

8
ответ дан 23 November 2019 в 21:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: