Sprawdź, czy instancja NSString jest zawarta w NSArray

80

Mam tablicę z wieloma ciągami i chcę sprawdzić, czy określony ciąg jest zawarty w tablicy. Jeśli używam containsObjectkomunikatu: w tablicy, otrzymuję poprawne wyniki. Czy wszystkie NSStringobiekty z tym samym ciągiem wskazują ten sam obiekt? Albo dlaczego containsObject: działa?

Wielebny
źródło

Odpowiedzi:

171

Tak, zakodowane na stałe NSStrings (literały ciągów) (czyli dowolne @"..."w kodzie źródłowym) są zamieniane na ciągi, które istnieją w nieskończoność podczas działania procesu.

Jednak NSArray „s containsObject:metody połączenia isEqual:na swoich obiektach, stąd nawet tworzone dynamicznie strunowe takie jak [NSString stringWithFormat:@"%d", 2] wróciYES w przykładowym fragmencie.
Dzieje się tak, ponieważ metoda NSString isEqual:(a dokładniej jej isEqualToString:) została zaimplementowana, aby być świadomym treści (w przeciwieństwie do porównywania tożsamości wskaźników) i dlatego zwraca YESkażdą parę ciągów zawierających tę samą sekwencję znaków (w czasie porównania), bez względu kiedy zostały stworzone.

Aby sprawdzić równą (wskaźnikową) tożsamość, musisz wyliczyć swoją tablicę i porównać za pomocą

(czego najprawdopodobniej byś nie chciał).

Lub w wygodniejszy sposób:

(najprawdopodobniej tego też byś nie chciał).


Podsumowując:

Zatem powodem, dla którego otrzymujesz pozytywną odpowiedź, NIEcontainsObject: jest fakt, że ciągi literalne mają tę samą stałą instancję, ALE ponieważ są to wywołania konwencji , które są świadome treści.containsObject:isEqual:

Może chcesz przeczytać (krótka) dokumentacji isEqual:z protokołem NSObject .

Regexident
źródło
17

containsObject:wykonuje sprawdzenie wartości, a nie sprawdzenie wskaźnika. Używa isEqual:metody zdefiniowanej przez NSObject i nadpisywanej przez inne obiekty do testowania. Dlatego jeśli dwa ciągi zawierają tę samą sekwencję znaków, zostaną uznane za takie same.

W niektórych przypadkach bardzo ważne jest rozróżnienie między testowaniem wskaźników i testowaniem wartości. Stałe ciągi zdefiniowane w kodzie źródłowym są łączone przez kompilator, dzięki czemu są tym samym obiektem. Jednak ciągi tworzone dynamicznie nie są tym samym obiektem. Oto przykładowy program, który to zademonstruje:

Wynik tego programu to:

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

ughoavgfhw
źródło
4

Możesz użyć, containsObjectaby dowiedzieć się, czy określony ciąg istnieje,

isuru
źródło