Почему бы не выдать исключение, если [super init] возвращает nil? - PullRequest
12 голосов
/ 04 июля 2011

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

- (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's not"] userInfo:nil]
    }
    return self;
}


Следствие этоговопрос в том, «при каких условиях [super init] вернет nil и , разве вы не справитесь с этим в методе init? »

Ответы [ 4 ]

10 голосов
/ 04 июля 2011

Не совсем.

с:

self = [super init];

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

if(self)

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

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

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

РЕДАКТИРОВАТЬ: читал руководство по какао, и нашел его в разделе Обработка ошибок:

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

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

10 голосов
/ 04 июля 2011

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

6 голосов
/ 04 июля 2011

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

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

3 голосов
/ 04 июля 2011

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

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

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

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

...