Что происходит для выделения в случае сбоя initWithX? - PullRequest
1 голос
/ 25 марта 2011

Обычная практика - писать MyClass* obj = [[MyClass alloc] initWithX:X] в Objective-C. initWithX обычно определяется как

- (MyClass*) initWithX: (MyArgClass*) X {
    if (self = [super init])  {
        // initialize
    }
    return self;
} 

Мой вопрос: что делать, если инициализация не удалась? Я не хочу бросать исключения, но как мне указать ошибку? Если я верну nil, вызывающая сторона не сможет отпустить указатель.

Ответы [ 2 ]

3 голосов
/ 25 марта 2011

Если по какой-либо причине инициализация не удалась, вы должны освободить себя.Для исключения, которое может произойти в вашей инициализации, вам нужно добавить вас @try @catch в зависимости от ситуации, чтобы вы могли выпустить self.

- (MyClass*) initWithX: (MyArgClass*) X {
    if (self = [super init])  {
        // initialize
        if(myInitializationCodeFailed)
        {
                [self release];
                return nil;
        }
    }
    return self;
}

Обновление

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

- (MyClass*) initWithX: (MyArgClass*) X error:(NSError**)error {

Как указывает Алексей Шолик в комментариях, проверьте Обработка ошибки инициализации раздел выделения и инициализации объектов.

1 голос
/ 25 марта 2011

В основном, это отвечает на ваш вопрос.

Ошибка инициализации обработки

Как правило, если во время инициализации возникает проблема, вы должны вызвать метод release для self и вернуть nil.

Существуют два основных последствия этой политики:

  • Любой объект (будь то ваш собственный класс, подкласс или внешний вызывающий объект), который получает nil от метода инициализатора, должен иметь возможность иметь дело с ним. В маловероятном случае, когда вызывающий установил какие-либо внешние ссылки на объект до вызова, вы должны отменить любые подключения.
  • Вы должны убедиться, что методы dealloc безопасны при наличии частично инициализированных объектов.

...

...