2011-04-27 100 views
71

我有一堆字符串的數組,我想檢查一個字符串是否包含在數組中。如果我在陣列上使用containsObject:消息,我會得到正確的結果。將所有NSString對象與相同的字符串指向同一個對象?或者爲什麼containsObject:工作?檢查NSString實例是否包含在一個NSArray中

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

回答

156

是,硬編碼NSString的(字符串)中(即在源代碼中的任何@"...")被轉換成了無限期地存在,而你的進程正在運行的字符串。

然而的NSArraycontainsObject:方法調用isEqual:它的對象,因此甚至是動態創建的字符串[NSString stringWithFormat:@"%d", 2]會在你的示例代碼段返回YES
這是因爲的NSString的isEqual:(或更精確地其isEqualToString:)方法被實現爲內容感知(相對於比較指針身份)從而對任何一對含有字符的非常相同的序列串的返回YES(在時間比較),無論他們如何以及何時創建。

要檢查你不得不枚舉陣列,並且通過

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

(你很可能不會想,雖然)比較相等(指針 - )身份。

或者以更方便的方式:

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

(你很可能不希望這樣一個其一)。


總結:

所以你從containsObject:得到肯定答覆的原因是因爲文字串,因爲containsObject:通過公約要求isEqual:共享同一個恆定的情況下, ,這是內容意識。

您可能想要從NSObject protocol中閱讀isEqual:的(簡短)文檔。

16

containsObject:執行值檢查,而不是指針檢查。它使用NSObject定義的isEqual:方法並被其他對象覆蓋以進行測試。因此,如果兩個字符串包含相同的字符序列,則它們將被視爲相同。

指針測試和值測試之間的區別在某些情況下非常重要。源代碼中定義的常量字符串由編譯器組合,以便它們是同一個對象。但是,動態創建的字符串不是同一個對象。下面是一個例子程序,這將證明這一點:

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 = = constantString2
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] ==是
2011-04-27 17:10:54.706 a.out [41699:903] theArray包含:
constantString:1
constantString2:1
dynamicString:1

相關問題