こんにちは。
目玉焼きにかけるのはソースではなく醤油派、mukaiyachiです。
6月3日にWWDCでAppleから新しいプログラミング言語『Swift』の発表がありました。
(※WWDC・・・Appleの主催で毎年開催される開発者のお祭り)
『Swift』は『iOS』および『OS X』のためのプログラミング言語です。
現在は『iOS』や『OS X』用のアプリは主に『Objective-C』という言語で開発が行われています。
今後Swiftのシェアがのびる可能性もありますがしばらくはObjective-Cが主流となるのではないかと思います。
今回はそのObjective-Cの『null』についてです。
『null』とはプログラミング言語で「何も無いこと」などを表す際に使われます。
この『null』を表現する言葉がObjective-Cには4つ存在します。
それが『nil』 『Nil』 『NULL』 『NSNull』です。
はずかしながらこれらの違いについてうろ覚えでしたので改めて調べてみました。
—————————————————————————————————————————-
【nil】
Objective-Cのオブジェクト(id型)に対して空という意味。
nilはnullオブジェクトを表し、オブジェクトが未初期化であることや、
クリアされた状態であることを表す。
例:
1 |
NSString str = nil; |
—————————————————————————————————————————-
【Nil】
Objective-Cのクラスに対して空という意味。
nullクラスオブジェクト。
例:
1 |
Class A = Nil; |
—————————————————————————————————————————-
【NULL】
ポインタに対して空という意味。
このNULLはC言語互換のNULL。
Objective-CはC言語と互換性がある。
例:
1 |
char *pointer = NULL; |
—————————————————————————————————————————-
【NSNull】
空の意味を表すオブジェクト。
NSNullはクラスであり、nullを表すオブジェクト。
シングルトンインスタンスなので、常に同じ一つのインスタンスを指す。
例:
1 |
NSArray *array = [NSArray arrayWithObjects:@"value1", [NSNull null], @"value3", nil]; |
—————————————————————————————————————————-
Objective-Cでは普段nullを表現するときはnilを使います。
ただし、NSArrayやNSDictionaryなどのコレクションにはnilを追加することができません。
そのかわりNSNullのインスタンス、[NSNull null]を用います。
[誤ったNSArrayへのnullの追加の仕方]
1 2 3 4 5 |
//配列を作成 NSMutableArray *array = [[NSMutableArray alloc] initWithCapacity:0]; [array addObject:@"value1"]; [array addObject:nil]; //エラーになる [array addObject:@"value3"]; |
[正しいNSArrayへのnullの追加の仕方]
1 2 3 4 5 |
//配列を作成 NSMutableArray *array = [[NSMutableArray alloc] initWithCapacity:0]; [array addObject:@"value1"]; [array addObject:[NSNull null]]; //エラーにならない [array addObject:@"value3"]; |
nilをNSArrayやNSDicitonaryで利用の場面は他にあって、NSNullの例のように最後にnilを付け加えることで、要素の終端位置を示すために使われます。
1 |
NSArray *array = [NSArray arrayWithObjects:@"value1", @"value2", @"value3", nil]; |
この最後のnilを付け加えるということをしないと、エラーで落ちるので注意が必要です。
また、NSNullとnilは別物なので、nilとの比較だけ行っているとエラーが出る場合があるので注意しましょう。
そういったときはnilではなくNSNullが入ってきている可能性があります。
[誤った比較の仕方]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
//配列を作成 NSMutableArray *array = [[NSMutableArray alloc] initWithCapacity:0]; [array addObject:@"value1"]; [array addObject:[NSNull null]]; [array addObject:@"value3"]; //配列から0番目の要素を取得 NSString *str = [array objectAtIndex:0]; //エラーになるのでNG if(str != nil && str.length > 0){ NSLog(@"%@%@", @"間違った判定1", [array objectAtIndex:0]); } //この場合は中身が空でも常に真と評価して意図しないことになるのでNG if(str){ NSLog(@"%@%@", @"間違った判定2",[array objectAtIndex:0]); } |
[正しい比較の仕方]
1 2 3 4 5 6 7 8 9 10 11 12 13 |
//配列を作成 NSMutableArray *array = [[NSMutableArray alloc] initWithCapacity:0]; [array addObject:@"value1"]; [array addObject:[NSNull null]]; [array addObject:@"value3"]; //配列から0番目の要素を取得 NSString *str = [array objectAtIndex:0]; //変数strの中身が空ではない場合ログが出力される if(! [str isEqual:[NSNull null]] && [str length] > 0){ NSLog(@"%@%@", @"正しい判定", [array objectAtIndex:0]); } |
さらに、nilは他の言語と異なり、メッセージを送ることが許されています。
返却値は、返却値の型がid型のメッセージの場合はnilを返し、
intのようなC言語の型の場合は0を返します。
C言語のstructのような場合は返却値は未定義です。
nilとNilはともに(id)0と定義されています。
一方NSNullは、NSNullオブジェクトに存在しないメッセージを送ると
NSINvalidArgumentExceptionの例外を投げ、これをキャッチしなかった場合は
クラッシュしてしまいます。
通常iOSアプリ等を作る際にはほとんどNilは使用することはありませんし、
NULLもC言語を使用するようなプログラムでなければほとんど使うことはないでしょう。
しかしnilとNSNullはクラッシュしたとき原因がわからなくて困る可能性があるので、
そうならないようこの2つの使い方の違いは最低限忘れないようにしたいです。