Почему мы все проверяем, есть ли (self) в методах init?
Я делаю это религиозно уже пару лет. Проверка правильности self
после вызова методов [super init...]
:
self = [super init];
if (self != nil) {
// initialize
}
return self;
Вы можете сделать это различными способами, так как этот вопрос красиво подводит итог, но этот вопрос касается синтаксиса, мой вопрос о концепции.
Недавно я получил вопрос от коллеги, который изучал Objective-C, и он спросил меня: "Почему я должен проверять существование себя, разве не очевидно, что это там?" и мой короткий ответ был "err, да, хорошо там случаи, когда он может потерпеть неудачу, и почему". Но длинный ответ заключается в том, что я действительно не понимаю себя, почему мы проверяем его везде, когда случаи, когда он может потерпеть неудачу, очень редки. Справочное руководство Apple рассказывает нам о некоторых конкретных случаях, например, при инициализации файлами или при работе с одиночными точками. Но они звучат как очень редкие исключения из правила, которое [super init]
должно просто работать.
Итак, мой вопрос для вас таков: Почему мы всегда проверяем достоверность самого себя? Мы просто внедряем его везде, чтобы поймать это одно исключение, где оно происходит? Почему бы просто не пропустить всю вещь if (self)
и инициализировать наш объект, если шансы его успеха будут на 100% (или это никогда не так)?
P.S. Я понимаю, что этот вопрос должен быть обманом, поскольку он настолько прост, но в моих поисковых запросах появилось много других вопросов о синтаксисе инициализации. Ссылки на Dupe приветствуются, приветствуют!
Ответы
Ответ 1
Здесь полезная старая статья по этому вопросу, включая также некоторые распространенные заблуждения относительно инициализатора. Я бы сказал, основная идея заключается в том, что конкретный класс не должен быть связан с реализацией своего суперкласса, поэтому мы всегда проверяем nil
в случае ошибки.
Ответ 2
uhm... это, безусловно, хороший вопрос, я бы хотел, чтобы я это сделал.
Я не эксперт в objective-c, но я постараюсь дать свое мнение, не опасаясь, что downvoter:-)
Я чувствую ваше разочарование, но:
err, yeah, well there instances where it can fail, so that why.
Это отличный ответ.
Я думаю, что вы не проверяете себя, но вы проверяете правильность инициализации супер объекта, для меня это другая точка зрения.
Я полагаю, что в любом случае всегда хорошо проверять, правильно ли был выделен и правильно инициализирован объект, особенно в objective-c, который находится поверх C со всеми проблемами выделения памяти маскарада. Init придет после "alloc", и предполагается инициализировать выделенный объект с помощью переменных и т.д.
Например, в таких языках, как Java, где цепочка конструкторов хорошо определена и проверена компилятором, неспособность построить объект приведет к ошибке с нулевым указателем при последующем использовании этого объекта. Часто распределение объекта в Java не требует ошибок, но часто использование методов должно быть окружено специальным блоком ошибок try/catch. Таким образом, проверка выполняется позже в жизненном цикле приложения.
В objective-c вместо этого у вас может быть объект nil по многим причинам, и если нет сбоя приложения, вы можете закончить отправку сообщения недопустимому объекту.
Я должен быть честным, при создании экземпляра непосредственно из подкласса NSObject я не знаю полезности проверки nil. Но если я расширяю класс в структуре или статический lib, предоставленный другими, я определенно буду чувствовать себя в безопасности с проверкой на достоверность объекта.