web-dev-qa-db-ja.com

NSRange:range.location!= NSNotFound vs. range.length> 0

アプリの1つで古いコードをいくつか調べて、問題が発生する可能性のある領域のコードを修正しています。

私は使用している古いコードをたくさん見ています...

NSRange range = //determine range here....
if(range.length > 0)
{
    //do stuff
}

そのコードは「問題ない」のでしょうか、それともこれに変更する必要がありますか?

NSRange range = //determine range here....
if(range.location != NSNotFound)
{
    //do stuff
}

これらの2つの方法は、本質的に同一ですか、それともそうではありませんか?

14
MikeS

2つのチェックは常に同一であるとは限りません。範囲がどのように生成されたかによって異なります。例:

NSRegularExpression *re = [NSRegularExpression
    regularExpressionWithPattern:@"(?= )" options:0 error:NULL];
NSTextCheckingResult *result = [re firstMatchInString:@"hello world"
    options:0 range:NSMakeRange(0, 11)];
NSLog(@"range = %@", NSStringFromRange(result.range));

範囲の長さは0ですが、その場所はNSNotFoundではなく5です。

12
rob mayoff

答えは、使用している関数/メソッドによって異なります。 NSRangeは単なる構造体であるため、呼び出す関数/メソッドのドキュメントを読む必要があります。

例:

NSRangeFromString
テキスト表現から範囲を返します。

... aStringに整数が含まれていない場合、この関数は、位置と長さの値が両方とも0であるNSRange構造体を返します。

この場合、NSNotFoundのチェックは機能しません。


-[NSString rangeOfString:]

... aStringが見つからないか空(@ "")の場合、{NSNotFound、0}を返します。

ここでは、場所がNSNotFoundになり、lengthが0になるため、どちらのチェックも機能することが文書化されていますが、NSNotFoundに対して場所をチェックすることをお勧めします。

6
Joe

NSNotFoundは「NSIntegerMax」として定義されています。同じ結果が得られたとしても、2番目のディスプレイははるかに読みやすく自己文書化されます。たぶん、あなたはそれらすべてを見つけてそれらを変えるべきではなく、ただ前進することに切り替えるべきです。

0
rooster117