Так, жорстко закодовані NSStrings (рядкові літерали) (тобто будь-який @"..."
у вашому вихідному коді) перетворюються на рядки, які існують необмежено довго, поки ваш процес запущений.
Однак NSArray «s containsObject:
методу виклики 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:
, про що відомо вмісту.
Можливо, ви захочете прочитати (коротку) документацію isEqual:
з протоколу NSObject .