2012年11月08日

[NSString] 空文字列の判定


NSStringを返すメソッドがあって結果が空文字列の場合の判定をしたいという場面はよくある。
この時、戻り値を @"" と比較して空文字列かどうか判定するのは適切とは言えない。


if ( aString == @"" ) {
NSLog(@"Same!");
} else {
NSLog(@"Different!");
}


これはC言語でも同じだが、aStringはNSStringオブジェクトへのポインタなのだからこの比較はオブジェクトが同じアドレスにあるかどうかでしかない。

そして上記のように@""と書くとこれは文字列定数として静的に確保されたメモリ上のオブジェクトのことである。だから動的に作成した空文字列は通常は別のメモリアドレスに配置される。

下記がその例。

int main(int argc, const char * argv[])
{
@autoreleasepool {
NSString *aString;
aString = @"";
NSLog(@"[%@] %p",aString,aString);
if ( aString == @"" ) {
NSLog(@"Same!");
} else {
NSLog(@"Different!");
}
aString = [NSString stringWithFormat:@"%@",@""];
NSLog(@"[%@] %p",aString,aString);
if ( aString == @"" ) {
NSLog(@"Same!");
} else {
NSLog(@"Different!");
}
}
return 0;
}


実行結果


2012-11-08 13:28:18.699 CodeTest[63648:303] [] 0x1000010d0
2012-11-08 13:28:18.701 CodeTest[63648:303] Same!
2012-11-08 13:28:18.701 CodeTest[63648:303] [] 0x7fff7e6b5f90
2012-11-08 13:28:18.701 CodeTest[63648:303] Different!


空文字列かどうかは通常下記にて比較する。


if ( [aString compare:@""] == NSOrderedSame ) {
NSLog(@"Same!");
} else {
NSLog(@"Different!");
}
if ( [aString length] == 0 ) {
NSLog(@"Same!");
} else {
NSLog(@"Different!");
}


後者の方法のほうがより優れている。結果が正常な文字列にならなければ空文字列ではなく nil を返すような仕様であっても、lengthが0を返すから(nilへのメッセージ送信の結果はnilまたは0になる)。


この方法はNSArrayの場合にも応用できる。結果を配列で返すメソッドがあったとして、適合するデータがひとつもなかったらどうすればいいだろうか?nilを返す?要素数が0個のオブジェクトを返す?nilのほうがわかりやすいと思うのだが、そうすると呼び出された側で結果の個数を判定してnilを返すかどうか処理を振り分ける必要がある。呼び出した側でも結果がnilかどうかで分岐するのであれば無駄である。

結果の判定は要素数が0個かどうかでだけ判断する。

if ( [anArray count] == 0 ) {
NSLog(@"no item");
} else {
NSLog(@"has items");
}


これはanArray が nilであっても期待通りに動作する。

呼び出された側では以下のように書き、結果が0個でもそのまま返すように書けばよいが、nilを返すようにしてもそのまま動作する。

NSMutableArray *result = [NSMutableArray array];
for ( ... ) {
...
}
return result;
posted by 永遠製作所 at 15:05| 東京 ☀| Comment(0) | TrackBack(0) | Cocoa | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント: [必須入力]

※ブログオーナーが承認したコメントのみ表示されます。
この記事へのトラックバックURL
http://blog.seesaa.jp/tb/300927014
※ブログオーナーが承認したトラックバックのみ表示されます。
※言及リンクのないトラックバックは受信されません。

この記事へのトラックバック