title: Followup to returning nil from a [[class alloc] init]
body: <p>As follow-up of sorts to <a href="https://stackoverflow.com/questions/3470550/is-returning-nil-from-a-class-alloc-init-considered-good-practice/13279913">Is returning nil from a [[class alloc] init] considered good practice?</a>, there's a case that I haven't seen any discussed much: what to do with an init that fails some preconditions before it can call the next init?</p>
  
  <p>Example, suppose in this initWithStuff: method being passed nil or in general having no value to pass to initWithValue: is an absolute failure and we definitely want to return nil.</p>
  
  <pre><code>- (id)initWithStuff:(Stuff *)inStuff {
    if (!inStuff || ![inStuff hasValidValue])
    {
      // can't proceed to call initWithValue: because we have no value
      // so do what?
      return nil;
    }
    NSInteger value = [inStuff integerValue];
    return [super initWithValue:value];
  }
  </code></pre>
  
  <p>Perhaps a clearer example is if the designated initializer method we wrap takes an object pointer and throws an exception if its passed nil. We definitely need to short-circuit that init call that would cause an exception.</p>
  
  <p>My guess: init by any means possible, and only then release self before returning nil. If necessary, call bare init or any other initializer that will work to finish putting self into a known state before releasing it.</p>
  
  <pre><code>  // can't proceed to call super's initWithValue: because we have no value
    // so do what? do this:
    self = [super init]; // or initWithValue:0
    [self release];
    return nil;
  </code></pre>
  
  <p>And if there were no such initializer that will work without valid data, I guess one would need to construct some valid, dummy data. Or complain to its author and until then just return nil and live with the leak :^)</p>
  
  <p>Also, how does ARC affect the situation?</p>
  
  <p>My guess: still finish init by any means possible, then just return nil. You'd think setting self might be redundant, but in some cases it's not. In any case, it but it needs to be there to silence a compiler warning.</p>
  
  <pre><code>  // can't proceed to call super's initWithValue: because we have no value
    // so do what? do this:
    self = [super init]; // finish init so ARC can release it having no strong references
    return nil;
  </code></pre>
  
  <p>Are my guesses wrong in any way?</p>