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

2019-05-22 15:54发布

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;
}

5条回答
可以哭但决不认输i
2楼-- · 2019-05-22 16:15

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.

查看更多
在下西门庆
3楼-- · 2019-05-22 16:19
  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.

查看更多
时光不老,我们不散
4楼-- · 2019-05-22 16:20

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

查看更多
Anthone
5楼-- · 2019-05-22 16:23

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.

查看更多
虎瘦雄心在
6楼-- · 2019-05-22 16:26

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

查看更多
登录 后发表回答