开发者

NS String comparison fails with stringWithFormat

I have two NSStrings with the same value

this failed for me:

if (button.controlName == controlName) {
        return button;
    }

this wor开发者_StackOverflowked:

if ([button.controlName compare: controlName] == NSOrderedSame) {
        return button;
    }

Is this just how strings are compared in objective c? Or should the first statement have worked as well? Why might the first statement have failed? I know it worked for other strings.

The strings it does not work for are initialized like this:

button.controlName = [NSString stringWithFormat:@"controlName%d", i]


With NSString you should use isEqualToString: instead of compare.

[button.controlName isEqualToString:controlName]

Read more the why (and also why it worked for some other strings)

Objective-C is a fairly thin layer on top of standard C. As a result obj-c, just as in normal c, doesn't have operator overloading.

NSString *controlName = @"bobDole";

The above code creates a pointer to the string @"bobDole", controlName is not the value itself, but instead is really just a long integer that says the memory address of an object.

When using pointers and comparing them using the == operator like (mutableCopy is being used to prevent the compiler from optimizing out the validity of this example.)

NSString *string1 = @"bobDole";
NSString *string2 = [string1 mutableCopy];

NSLog(@"%d", string1 == string2);

The above code will always print false (or zero in this case), even though both objects are NSStrings, and both contain the value of @"bobDole". This is because the value of string1 is actually a hex number like 0x0123456 and string2 could be something like 0x0987654. So really the above comparison looks like this to the computer:

NSLog(@"%d", 0x0123456 == 0x0987654);

So when comparing strings (or any other object), always use one of the isEqual methods, never use the == operator.

Now as to why it worked for some other strings:

As mentioned above when using the == operator you're actually doing pointer comparison. You'll also notice in my above example I used mutableCopy instead of the following:

NSString *string1 = @"bobDole";
NSString *string2 = @"bobDole";

The reason I did such was that the compiler will look at those two statements know they share the same immutable value and optimize them so they point at the same value in memory. Thus making the pointer values of the two identical.

The compiler also makes the same optimizations for these methods of string initialization.

NSString *string3 = [NSString stringWithString:@"bobDole"];
NSString *string4 = [NSString stringWithString:string1];
NSString *string5 = [string1 copy];  

Because of this optimization by the compiler and runtime all 5 pointers point to the same memory location and are thus equal to each other when compared via ==.

This may be kinda long, but I tried to make it accessible and understandable. Hope it helps.


1st statement just compares pointers, but not string values, so to compare strings you should use -isEqualToString as Bryan points.


There's a method called isEqualToString to compare two NSStrings.

if([button.controlName isEqualToString:controlName])
   ...
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜