Перевірте, чи екземпляр NSString міститься в NSArray


80

У мене є масив із купою рядків, і я хочу перевірити, чи міститься певний рядок у масиві. Якщо я використовую containsObjectповідомлення: у масиві, я отримую правильні результати. Чи всі NSStringоб'єкти з однаковим рядком вказують на один і той же об'єкт? Або чому containsObject: працює?

Відповіді:


171

Так, жорстко закодовані NSStrings (рядкові літерали) (тобто будь-який @"..."у вашому вихідному коді) перетворюються на рядки, які існують необмежено довго, поки ваш процес запущений.

Однак NSArray «s containsObject:методу виклики isEqual:на своїх об'єктах, отже , навіть динамічно створювані рядки , такі , як [NSString stringWithFormat:@"%d", 2] би повернутисяYES в вашому зразку фрагмента коду.
Це пов’язано з тим, що метод NSString isEqual:(або точніше його isEqualToString:) реалізований для обізнаності про вміст (порівняно з порівнянням ідентифікаторів покажчиків) і, таким чином, повертається YESдля будь-якої пари рядків, що містять ту саму послідовність символів (під час порівняння), незалежно від того, як і коли вони були створені.

Щоб перевірити рівність (покажчика) ідентичності, вам доведеться перерахувати свій масив і порівняти через

(чого ви, швидше за все, не хотіли б).

Або більш зручним способом:

(ви, швидше за все, цього не хотіли б).


Підводячи підсумки:

Отже, причина, з якої ви отримуєте позитивну відповідь containsObject:, НЕ тому, що буквальні рядки мають один і той же константний екземпляр, А через те, що containsObject:за звичайними викликами isEqual:, про що відомо вмісту.

Можливо, ви захочете прочитати (коротку) документацію isEqual:з протоколу NSObject .


17

containsObject:виконує перевірку значення, а не перевірку покажчика. Він використовує isEqual:метод, визначений NSObject і замінений іншими об'єктами для тестування. Отже, якщо два рядки містять однакову послідовність символів, вони вважатимуться однаковими.

У деяких випадках різниця між тестуванням покажчика та тестуванням цінностей є дуже важливою. Постійні рядки, визначені у вихідному коді, комбінуються компілятором так, щоб вони були одним і тим же об’єктом. Однак рядки, створені динамічно, не є однаковим об'єктом. Ось приклад програми, яка продемонструє це:

Результатом роботи цієї програми є:

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] == ТАК 27.04.2011
17: 10: 54.706 a.out [41699: 903] theArray містить:
constantString: 1
constantString2: 1
dynamicString: 1


4

Ви можете використовувати, containsObjectщоб з'ясувати, чи існує певний рядок,

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.