Pragmatic ball boy

iOSを中心にやってる万年球拾いの老害エンジニアメモ

Objective-Cのif文の判定 : if(self) VS if(self = [super init])

ちょっと前から気になっていたことがあるので確認してみた

appleのドキュメント内のイニシャライザの書き方で

self = [super init];
if (self){
}

のパターンと

if (self = [super init]){
}

のパターンがあり、後者になんか違和感があったので、ほんとにちゃんと動くのか確認してみた。
というのもC/C++ではif文内に代入文を書くのは結構よく禁じられており、これって代入文だと常に非0になるからなんだっけ?それとも単に書き間違えが発見しづらいだけだったっけということもあり、この際ちゃんと調べてみたわけです。

結論から言うと上のはどちらも正解です。

SuperTestClass.m

#import "SuperTestClass.h"

@implementation SuperTestClass
- (id)init{
return nil;
}
@end

TestClass.h
#import "SuperTestClass.h"

@interface TestClass : SuperTestClass

@end

TestClass.m
#import "TestClass.h"

@implementation TestClass

- (id)init{
self = [super init];
if (self) {
NSLog(@"instance created 1");
}
if (self = [super init]){
NSLog(@"instance created 2");
}
int i;
if ( i = 0 ) {
NSLog(@"instance created 3");
}
if ( i = 1 ) {
NSLog(@"instance created 4");
}
return self;
}

@end

これをTestClass をalloc,initすると結果は
instance created 4 だけ出力されます。

if文の中で代入すると、代入した結果が評価されるということになります。
ちなみに、.mでなく.cでCで書いてみましたが同じ結果でした。


結果的にはこうですが、
個人的にはif文の中での代入は紛らわしい以外の何者でもないのでやめたほうがいいと思います。
一行で済むから構わん!という意見もありそうですが、Appleのドキュメントやソースでもバラバラなのはこの辺の宗教戦争が勃発しているのでしょうか・・