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

Почему бы не выбрасывать исключение, если [super init] возвращает nil?

Это считается типичным

- (id)init {
    self = [super init];
    if (self) {
        // <#initializations#>
    }
    return self;
}

но не было бы лучше пойти с чем-то вроде этого, которое на самом деле отвечает соответствующим образом?

- (id)init {
    self = [super init];
    if (self) {
        // <#initializations#>
    } else {
       @throw [NSException exceptionWithName:NSInternalInconsistencyException reason:@"you think your constructor is executing, but it not"] userInfo:nil]
    }
    return self;
}


Следствием этого вопроса является "при каких условиях [super init] return nil и вы не должны обрабатывать это в методе init?"

4b9b3361

Ответ 1

Одна из причин, почему вы должны делать то, что говорит JustSid:

В объектно-ориентированном дизайне вы всегда должны указывать код, как будто вы, возможно, передадите свой класс другому проекту другим разработчиком. Поэтому вы не можете предположить, что неудача при инициализации в его проекте может быть такой же плохой, как, вероятно, в вашей. Может быть, этот разработчик вам через 5 лет. Представьте себе, что вы решили исправить свои 200 классов, которые вы хотите использовать повторно.

Ответ 2

Нет, исключения из Objective-C предназначены для состояний, от которых вы действительно не можете восстановить, а не просто для того, чтобы показать, что операция завершилась неудачно. Если инициализатор не работает, просто верните нуль, чтобы показать его.

Ответ 3

Не совсем.

с:

self = [super init];

вы вызываете ваш метод суперкласса init, который только в случаях RARE возвращает nil. (например, если система имеет низкую память, и у вас есть другие проблемы).

if(self)

это не пройдет, если экземпляр не возвращается (он равен нулю), поэтому нет необходимости в else.

старый способ был

if((self = [super init))
{
    // do initialization
}
return self

EDIT: читал руководство Cocoa Fundementals и нашел это в разделе "Обработка ошибок":

Если ошибка, встречающаяся в методе реализация представляет собой системный уровень или Objective - C ошибка времени выполнения, создание и при необходимости, вызывать исключение и обрабатывайте его локально, если это возможно. В Cocoa, исключения обычно зарезервировано для программирования или неожиданно ошибки времени выполнения, такие как внешние ограничения доступ к коллекции, попытки мутировать неизменяемые объекты, отправка недействительных сообщение и потерять соединение с оконный сервер. Вы обычно принимаете забота об этих ошибках с исключениями когда приложение создается а не во время выполнения. Cocoaпредопределяет несколько исключений, которые вы может ловить обработчик исключений. Для получения информации о предопределенных исключения и процедура и API для получения и обработки исключений, см. разделы "Исключение программирования".

Для других видов ошибок, в том числе ожидаемые ошибки времени выполнения, обратный нуль, NO, NULL или какой-либо другой тип - подходящий форма нуля для вызывающего. Примеры из этих ошибок включают неспособность для чтения или записи файла, отказа инициализировать объект, неспособность установить сетевое соединение или неспособность найти объект в коллекция. Используйте объект NSError, если вы считаете необходимым вернуться Дополнительная информация о ошибка отправителю. Объект NSError инкапсулирует информацию о ошибки, включая код ошибки (который может быть специфичным для Mach, POSIX или OSStatus) и словарь специфическая для программы информация. отрицательное значение, которое напрямую (ноль, НЕТ и т.д.) должны быть главным показателем ошибки; если вы общаетесь более конкретно информация об ошибке, вернуть NSError объект косвенно в параметре метод.

Ответ 4

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

resultObject = [[[[class alloc] init] autorelease] someProperty];

Этот оператор выполняется полностью, даже если какой-либо вызов метода возвращает nil. Чтобы соответствовать этому, соглашение init должно возвращать нуль, если суперкласс делает это.

Как указывает JustSid, ObjC использует исключения только для неустранимых проблем.