Почему бы не выбрасывать исключение, если [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
?"
Ответы
Ответ 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 использует исключения только для неустранимых проблем.