2011-04-27 16 views
71

私は文字列の束を持つ配列を持っており、特定の文字列が配列に含まれているかどうかを確認したいと思います。アレイ上でcontainsObject:メッセージを使用すると、正しい結果が得られます。 NSString同じ文字列を持つオブジェクトはすべて同じオブジェクトを指していますか?または、なぜcontainsObjectが機能していますか?NSStringインスタンスがNSArrayに含まれているかどうか確認してください

NSArray *stringArray = [NSArray arrayWithObjects:@"1",@"2",@"3",anotherStringValue, nil]; 
if([stringArray containsObject:@"2"]){ 
    //DO SOMETHING 
} 

答えて

156

はい、ハードコードされたNSStrings(文字列リテラル)は(つまり、ソースコード内の任意の@"..."である)あなたのプロセスが実行中に無限に存在する文字列になっています。

しかしにNSArraycontainsObject:方法は、したがって[NSString stringWithFormat:@"%d", 2]としても、動的に作成された文字列はあなたのサンプルスニペットでYESを返します、そのオブジェクトにisEqual:を呼び出します。
のNSStringのisEqual:(またはより正確にはそのisEqualToString:)メソッドがコンテンツ認識するように実装されている(ポインタIDを比較対)とは、このように文字の非常に同一の配列を含む文字列の任意のペアのためYESを返すためである(時比較)は、いつ、どのように作成されたかにかかわらず。

(あなたが最も可能性が高いものの、たくないであろう)、あなたの配列を列挙し、

NSString *yourString = @"foo"; 
BOOL identicalStringFound = NO; 
for (NSString *someString in stringArray) { 
    if (someString == yourString) { 
     identicalStringFound = YES; 
     break; 
    } 
} 

を経由して比較する必要があると思い等しい(pointer-)身元を確認するために。

以上の便利な方法で:

BOOL identicalStringFound = [stringArray indexOfObjectIdenticalTo:someString] != NSNotFound; 

(あなたが最も可能性が高いのいずれか、このいずれかを望んでいないだろう)。


総括:

を慣例によりcontainsObject:isEqual:を呼び出すためのリテラル文字列が同じ一定の場合、しかしを共有するためですから、containsObject:から肯定応答を取得している理由は、ではありませんこれはコンテンツに対応しています。

NSObject protocolからisEqual:の短いドキュメントを読むことができます。

16

containsObject:は、ポインタチェックではなく、値チェックを実行します。 NSObjectで定義されたメソッドisEqual:を使用し、テストのために他のオブジェクトによってオーバーライドされます。したがって、2つの文字列に同じ文字列が含まれている場合、同じ文字列とみなされます。

ポインタテストとバリューテストの区別は、場合によっては非常に重要です。ソースコードで定義された定数文字列はコンパイラによって結合され、同じオブジェクトになります。ただし、動的に作成された文字列は同じオブジェクトではありません。ここでこのことを実証するプログラム例である:

int main(int argc, char **argv) { 
    NSAutoreleasePool *p = [NSAutoreleasePool new]; 
    NSString *constantString = @"1"; 
    NSString *constantString2 = @"1"; 
    NSString *dynamicString = [NSString stringWithFormat:@"%i",1]; 
    NSArray *theArray = [NSArray arrayWithObject:constantString]; 
    if(constantString == constantString2) NSLog(@"constantString == constantString2"); 
     else NSLog(@"constantString != constantString2"); 
    if(constantString == dynamicString) NSLog(@"constantString == dynamicString"); 
     else NSLog(@"constantString != dynamicString"); 
    if([constantString isEqual:dynamicString]) NSLog(@"[constantString isEqual:dynamicString] == YES"); 
     else NSLog(@"[constantString isEqual:dynamicString] == NO"); 
    NSLog(@"theArray contains:\n\tconstantString: %i\n\tconstantString2: %i\n\tdynamicString: %i", 
      [theArray containsObject:constantString], 
      [theArray containsObject:constantString2], 
      [theArray containsObject:dynamicString]); 
} 

このプログラムの出力である:

2011-04-27 17:10:54.686のa.out [41699:903] constantString = = constantString 2011-04-27 17:10:54.705 a.out [41699:903] constantString!= dynamicString
2011-04-27 17:10:54.706 a.out [41699:903] [constantString isEqual: dynamicString] == YES
2011-04-27 17:10:54.706 a.out [41699:903] theArrayには以下が含まれています:
constantString:1
constantString2:1
dynamicString:1

関連する問題