views:

121

answers:

4

Both the following resolve to True:

1)

@"foo" == @"foo" (is True)

2)

NSString *myString1 = @"foo";
NSString *myString2 = @"foo";
myString1 == myString2 (is True)

However, there are definitely times where two NSStrings cannot be compared using the equality operator, and [myString1 isEqualToString:myString2] is required instead. Can someone shed some light on this?

Thanks, Yarin

+2  A: 

In Cocoa strings are compared using NSString's isEqualToString: method.

Pointer comparison works in your case because the compiler is gentle enough to merge the two string literals to point to one object. There's no guarantee that two identical strings share one NSString instance.

Nikolai Ruhe
+2  A: 

The reason why == works is because of pointer comparison. When you create a new autoreleased NSString using @"", the compiler looks for another string like it in memory, and if it finds it, it will point to it, otherwise it will create a new one.

When comparing NSString instances, you should use the isEqualToString: method:

NSString *myString1 = @"foo";
NSString *myString2 = @"foo";
NSString *myString3 = [[NSString alloc] initWithString:@"foo"];
NSLog(@"%d", (myString2 == myString3))  //0
NSLog(@"%d", (myString1 == myString2)); //1
NSLog(@"%d", [myString1 isEqualToString:myString2]; //1
[myString3 release];
Jacob Relkin
All great answers. @Jacob, thanks for the sample explanation.
Yarin
Most compilers will also make `myString3` a pointer to the constant `"foo"` as an optimization, so generally, all three of these variables will point to the same memory location. This is true for both gcc and clang (with default options). Try compiling this: http://gist.github.com/578568
mipadi
+3  A: 

The equality operator == only compares pointer addresses. When you create two identical strings using the literal @"" syntax, the compiler will detect that they are equal, and only store the data once. Hence, the two pointers point to the same location. However, strings created by other means may contain identical data, yet be stored at different memory locations. Hence, you should always use isEqual: when comparing strings.

Note that isEqual: and isEqualToString: always return the same value, but isEqualToString: is faster.

David M.
+6  A: 

== compares locations in memory. ptr == ptr2 if they both point to the same memory location. This happens to work with string constants because the compiler happens to use one actual string for identical string constants. It won't work if you have variables with the same contents, because they'll point to different memory locations; use isEqualToString in such a case.

mipadi