Почему мы все проверяем if (self) в методах init? - PullRequest
12 голосов
/ 15 марта 2012

Я делаю это религиозно уже пару лет.Проверка правильности self после вызова [super init...] методов:

self = [super init];
if (self != nil) {
    // initialize
}
return self;

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

Недавно я получил вопрос от коллеги, который изучает Objective-C, и он спросил меня: «Почему я должен проверять существование себя, разве это не очевидно, что оно там?»и мой короткий ответ был: «Да, ну, есть случаи, когда он может потерпеть неудачу, вот почему».Но длинный ответ заключается в том, что я действительно не понимаю себя, почему мы проверяем это повсюду, когда случаи, когда это может потерпеть неудачу, очень редки. Справочное руководство Apple рассказывает нам о некоторых конкретных случаях, например, при инициализации с файлами или при работе с синглетонами.Но это звучит как очень редкое исключение из правила, что [super init] s должен просто работать.

Поэтому мой вопрос к вам таков: Почему мы всегда проверяем действительность себя? мы просто внедряем это везде, чтобы поймать это единственное исключение, где оно происходит?Почему бы просто не пропустить всю вещь if (self) и инициализировать наш объект, если шансы на его успех составляют 100% (или это никогда не так)?

PS Я понимаю, что этот вопрос, должно быть, дурапоскольку это так просто, но мои поисковые запросы получили много других вопросов о синтаксисе инициализации.Дупе ссылки приветствуются, ура!

Ответы [ 2 ]

7 голосов
/ 15 марта 2012

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

1 голос
/ 15 марта 2012

хм ... это определенно хороший вопрос, я бы хотел его решить.Я не эксперт в объективе-c, но я постараюсь высказать свое мнение, не боясь downvoter :-)

Я чувствую ваше разочарование, но:

err, yeah, well there's instances where it can fail, so that's why.

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

Я полагаю, что в любом случае всегда полезно проверить, правильно ли был выделен и инициализирован объект, особенно в target-c, который находится на вершине C со всеми проблемами выделения памяти в маскараде.Инициирование происходит после 'alloc', и предполагается, что выделенный объект инициализируется переменными и т. Д. *

Например, в таких языках, как Java, где цепочка конструкторов хорошо определена и проверена компилятором, в случае неудачисоздание объекта приведет к ошибке нулевого указателя при последующем использовании этого объекта.Зачастую размещение объекта в Java безошибочно, но часто использование методов должно быть окружено специальным блоком ошибок try / catch.Поэтому проверка выполняется позже в жизненном цикле приложения.

В target-c вместо этого у вас может быть нулевой объект по многим причинам, и если нет сбоя приложения, вы можете прекратить отправку сообщения недопустимому объекту.Я должен быть честным, когда создаю экземпляр непосредственно из подкласса NSObject, я не знаю полезности проверки nil.Но если я расширяю класс в фреймворке или статической библиотеке, предоставляемой другими, я бы определенно чувствовал себя в безопасности с проверкой правильности объекта.

...