Должен ли я всегда выпускать self для неудачных методов init?

Должен ли я всегда отпускать себя, когда есть сбой внутри init, или я должен делать это только в том случае, если сначала инициализировал переменные экземпляра?

Иными словами, этот шаблон действителен? Есть ли время, когда я не должен отпускать себя внутри метода init, или я должен предположить, что если поток управления вступает в init, у меня есть как минимум счет сохранения 1?

- (id)init
{
 if ((self = [super init]) == nil)
 {
  [self release];
  return nil;
 }

 //do some init stuff
 if (somethingFailed)
 {
  [self release];
  return nil;
 }
 return self;
}

Ответ 1

Если какая-либо проверка, которая вам нужна в вашем методе инициализации, терпит неудачу, то да, вы должны освободить self. Обратите внимание, однако, что если [super init] возвращает nil, нет смысла отправлять release на self, поскольку self is nil. Это на самом деле нахмурило Apple:

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

Пример:

- (id)init
{
   self = [super init];
   if(self) {
       // do some init stuff

       if (somethingFailed)
       {
          [self release]
          self = nil;
       }
   }

   return self;
}

Также см. документацию Mac Dev Center Обработка отказа инициализации