I have an array with a bunch of strings and I want to check if a certain string is contained in the array. If I use the containsObject: message on the array, I’m getting correct results. Do all NSString objects with the same string point to the same object? Or why is the containsObject: working?
NSArray *stringArray = [NSArray arrayWithObjects:@"1",@"2",@"3",anotherStringValue, nil];
if([stringArray containsObject:@"2"]){
//DO SOMETHING
}
Yes, hard-coded NSStrings (string literals) (that is any
@"..."in your source code) are turned into strings that exist indefinitely while your process is running.However NSArray‘s
containsObject:methods callsisEqual:on its objects, hence even a dynamically created string such as[NSString stringWithFormat:@"%d", 2]would returnYESin your sample snippet.This is because NSString’s
isEqual:(or more precisely itsisEqualToString:) method is implemented to be content aware (vs. comparing pointer identities) and thus returnsYESfor any pair of strings containing the very same sequence of characters (at time of comparison), no matter how and when they were created.To check for equal (pointer-)identity you’d have to enumerate your array and compare via
(which you most likely wouldn’t want, though).
Or in a more convenient fashion:
(you most likely wouldn’t want this one either).
Summing up:
So the reason you’re getting a positive reply from
containsObject:is NOT because literal strings share the same constant instance, BUT becausecontainsObject:by convention callsisEqual:, which is content aware.You might want to read the (short) documentation for
isEqual:from the NSObject protocol.