Подтвердить что ты не робот

Почему мы все проверяем, есть ли (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 приветствуются, приветствуют!

4b9b3361

Ответ 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, предоставленный другими, я определенно буду чувствовать себя в безопасности с проверкой на достоверность объекта.