NS String比较因stringWithFormat而失败

时间:2009-11-23 15:11:05

标签: iphone objective-c nsstring

我有两个具有相同值的NSStrings

对我来说失败了:

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

这有效:

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

这是在目标c中比较字符串的方式吗?或者第一个声明是否也有效?为什么第一个陈述失败了?我知道它适用于其他字符串。

它不起作用的字符串初始化如下:

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

3 个答案:

答案 0 :(得分:9)

使用NSString,您应该使用isEqualToString:而不是比较。

[button.controlName isEqualToString:controlName]

阅读更多原因(以及为什么它适用于其他一些字符串)

Objective-C是标准C之上的一个相当薄的层。结果obj-c,就像在普通c中一样,没有运算符重载。

NSString *controlName = @"bobDole";

上面的代码创建了一个指向字符串@"bobDole"的指针,controlName不是值本身,而是实际上只是一个表示对象内存地址的长整数。

使用指针并使用==运算符比较它们时(使用mutableCopy来阻止编译器优化此示例的有效性。)

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

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

上面的代码将始终打印为false(在这种情况下为零),即使两个对象都是NSStrings,并且都包含@“bobDole”的值。这是因为string1的值实际上是十六进制数,如0x0123456,string2可能是0x0987654。所以上面的比较对于计算机来说真的如此:

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

因此,在比较字符串(或任何其他对象)时,请始终使用isEqual方法之一,切勿使用==运算符。

现在为什么它适用于其他一些字符串:

如上所述,当使用==运算符时,您实际上正在进行指针比较。您还会在上面的示例中注意到我使用了mutableCopy而不是以下内容:

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

我这样做的原因是编译器将查看这两个语句,知道它们共享相同的不可变值并优化它们,因此它们指向内存中的相同值。从而使两个指针的值相同。

编译器也对这些字符串初始化方法进行了相同的优化。

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

由于编译器和运行时的这种优化,所有5个指针指向相同的内存位置,因此在通过==进行比较时彼此相等。

这可能有点长,但我试图让它易于理解。希望它有所帮助。

答案 1 :(得分:2)

第一个语句只是比较指针,而不是字符串值,所以为了比较字符串,你应该使用-isEqualToString作为布莱恩指出。

答案 2 :(得分:1)

有一种名为isEqualToString的方法来比较两个NSStrings。

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