简体   繁体   中英

iPhone - Use of self = [super init] when [super init] fails

What is the difference beetween :

// 1
-(id) init {
    self = [super init];
    if (self) {
        ... do init ....
    }
    return self;
}

// 2 - I guess it's exactly the same as previous
-(id) init {
    if (self = [super init]) {
        ... do init ....
    }
    return self;
}

// 3 - is this one a really bad idea and if yes, Why ?
-(id) init {
    self = [super init];
    if (!self) return nil;

    ... do init ....

    return self;
}

// 4 - I think this one sounds OK, no ? But what is returned... nil ?
-(id) init {
    self = [super init];
    if (!self) return self;

    ... do init ....

    return self;
}

EDIT : Added thanks to Peter M.

// 5 - I really like the readability of this one
-(id) init {
    if(!(self = [super init])) return self;  // or nil

    ... do init ....

    return self;
}

they all do the same thing but first one are commonly used because apple suggested

the second one was commonly used but it will introduce compiler warning on new version of Xcode so apple decided to change it to first one

  1. The common one used by Apple
  2. Does the same but the compiler does not know if you didn't mean == instead of = . You can block the warning by using another (...) around the expression, but it's not easy to read.
  3. This one would be preferred by any good coding standards (usually not as a one-liner but with bracers). When your initialization code is long, this one significantly increase readibility.
  4. The same as 3 but you lose some readibility. Returning nil makes the code easier to understand (maybe this is only my opinion, someone else can say 4 is better than 3).

In summary: use 1 or 3. When initialization code is long, you should use 3 to avoid having most of method code in one if block. Apple uses only 1 but don't follow it blindly. Apple has no documented coding standards and sometimes what they recommend is very questionable.

You can use 4 instead of 3 but don't mix 3 & 4 in your code.

1 is suggested simply because it's clear.

2 works, but is just bad practice. Don't embed logic in your conditionals if you don't have to.

3 makes my head hurt. Typically, you want to avoid negative checks if you can.

4 same as 3.

Both 1 and 2 are easier to read than 3 and 4, also because they are the one's used in Apple's code; many developers are used to 1 and 2.

Number 4 and 3 are the same, as if !self evaluates as true, then it means self is nil , so the statement return self is equivelant to return nil . Some people will say you shouldn't have multiple exit points (returns) in a method, but in reality having multiple return statements can cut down the number of if statements (which reduce the readability)

Number 2 has been common, however in the latest versions of xcode you will get a compiler warning if and if statement contains a single = (as many times it is a typo, when you intended to use == to compare BOOL values). To silence this warning you have to surround the statement with brackets, so instead of if (foo = bar) you would have if ((foo = bar))
But Apple must have realised that Number 2 is used a lot, and they added an exception to the rule, so you using it will now not cause a compiler warning.

As Number 2 is an exception to the rule, you shouldn't really use it. So that makes Number 1 the preferred method.

To add to the fray .. I prefer:

if(!(self = [super init]) ) return self;

Keeping it all on the one line, and no warnings in XCode 4.2 :D

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM