理解 NSString 比较

发布于 2024-09-18 19:01:45 字数 324 浏览 9 评论 0原文

以下两个比较的结果均为 true:

1)

@"foo" == @"foo";

2)

NSString *myString1 = @"foo";
NSString *myString2 = @"foo";
myString1 == myString2;

但是,有时两个 NSString 无法使用相等运算符进行比较,并且 [myString1 isEqualToString:myString2] 是必需的。有人可以解释一下吗?

Both the following comparisons evaluate to true:

1)

@"foo" == @"foo";

2)

NSString *myString1 = @"foo";
NSString *myString2 = @"foo";
myString1 == myString2;

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

夏日落 2024-09-25 19:02:22
  NSString *str1=[NSString stringWithFormat:@"hello1"];
    NSString *str2=[NSString stringWithFormat:@"hello1"];
    NSString *str3 = [[NSString alloc] initWithString:@"hello1"];




// == compares the pointer but in our example we are taking same string value to different object  using @  so it will point to same address so output will be TRUE condition
    if (str1==str2) {
        NSLog(@"Both String are equal");
    }
    else{
        NSLog(@"Both String not are equal");
    }


    // == compares the pointer but in our example we are taking same string value to different object but we have allocated different string so both object will pount to different address so output will be FALSE condition
    if (str1==str3) {

        NSLog(@"Both String are equal");
    }
    else{
        NSLog(@"Both String not are equal");

    }


  // compare:= compares the values of objects so output will be TRUE condition
    if ([str1 compare:str3]== NSOrderedSame) {
        NSLog(@"Both String are equal");

    }
    else{
        NSLog(@"Both String not are equal");

    }


    // isEqual compares the values of objects so output will be TRUE condition

    if ([str1 isEqual:str2]) {

        NSLog(@"Both String are equal");
    }
    else{
        NSLog(@"Both String not are equal");

    }

    // isEqual compares the values of objects so output will be TRUE condition

    if ([str1 isEqual:str3]) {

        NSLog(@"Both String are equal");
    }
    else{
        NSLog(@"Both String not are equal");

    }


    // isEqualToString compares the values of objects so output will be TRUE condition
    if ([str1 isEqualToString:str2]) {

        NSLog(@"Both String are equal");
    }
    else{
        NSLog(@"Both String not are equal");

    }


    // isEqualToString compares the values of objects so output will be TRUE condition
    if ([str1 isEqualToString:str3]) {

        NSLog(@"Both String are equal");
    }
    else{
        NSLog(@"Both String not are equal");

    }

    // == compares the pointers since we have initialized the same value to first object so the pointer be be same for same value so output will be TRUE condition
    if (str1==@"hello1") {

        NSLog(@"Both String are equal");
    }
    else{
        NSLog(@"Both String not are equal");

    }
  NSString *str1=[NSString stringWithFormat:@"hello1"];
    NSString *str2=[NSString stringWithFormat:@"hello1"];
    NSString *str3 = [[NSString alloc] initWithString:@"hello1"];




// == compares the pointer but in our example we are taking same string value to different object  using @  so it will point to same address so output will be TRUE condition
    if (str1==str2) {
        NSLog(@"Both String are equal");
    }
    else{
        NSLog(@"Both String not are equal");
    }


    // == compares the pointer but in our example we are taking same string value to different object but we have allocated different string so both object will pount to different address so output will be FALSE condition
    if (str1==str3) {

        NSLog(@"Both String are equal");
    }
    else{
        NSLog(@"Both String not are equal");

    }


  // compare:= compares the values of objects so output will be TRUE condition
    if ([str1 compare:str3]== NSOrderedSame) {
        NSLog(@"Both String are equal");

    }
    else{
        NSLog(@"Both String not are equal");

    }


    // isEqual compares the values of objects so output will be TRUE condition

    if ([str1 isEqual:str2]) {

        NSLog(@"Both String are equal");
    }
    else{
        NSLog(@"Both String not are equal");

    }

    // isEqual compares the values of objects so output will be TRUE condition

    if ([str1 isEqual:str3]) {

        NSLog(@"Both String are equal");
    }
    else{
        NSLog(@"Both String not are equal");

    }


    // isEqualToString compares the values of objects so output will be TRUE condition
    if ([str1 isEqualToString:str2]) {

        NSLog(@"Both String are equal");
    }
    else{
        NSLog(@"Both String not are equal");

    }


    // isEqualToString compares the values of objects so output will be TRUE condition
    if ([str1 isEqualToString:str3]) {

        NSLog(@"Both String are equal");
    }
    else{
        NSLog(@"Both String not are equal");

    }

    // == compares the pointers since we have initialized the same value to first object so the pointer be be same for same value so output will be TRUE condition
    if (str1==@"hello1") {

        NSLog(@"Both String are equal");
    }
    else{
        NSLog(@"Both String not are equal");

    }
┊风居住的梦幻卍 2024-09-25 19:02:15

看看这个例子:

NSString *myString1 = @"foo";
NSMutableString *myString2 = [[NSMutableString stringWithString:@"fo"] stringByAppendingString: @"o"];

NSLog(@"isEquality: %@", ([myString1 isEqual:myString2]?@"+":@"-")); //YES
NSLog(@"isEqualToStringity: %@", ([myString1 isEqualToString:myString2]?@"+":@"-")); //YES
NSLog(@"==ity: %@", ((myString1 == myString2)?@"+":@"-")); // NO

所以,编译器很可能使用 isEqualToString 方法来处理 NSString 的 isEquals 和取消引用指针,尽管它没有这样做。正如您所看到的,指针是不同的。

Check out this example:

NSString *myString1 = @"foo";
NSMutableString *myString2 = [[NSMutableString stringWithString:@"fo"] stringByAppendingString: @"o"];

NSLog(@"isEquality: %@", ([myString1 isEqual:myString2]?@"+":@"-")); //YES
NSLog(@"isEqualToStringity: %@", ([myString1 isEqualToString:myString2]?@"+":@"-")); //YES
NSLog(@"==ity: %@", ((myString1 == myString2)?@"+":@"-")); // NO

So, the compiler is likely to use isEqualToString method to process isEquals for NSString's and dereference pointers, though it had not to. And the pointers are different, as you see.

演多会厌 2024-09-25 19:02:09

一个示例演示了地址比较作为字符串比较的替代项将如何被破坏:

    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    NSString *s1 = @"foo";
    NSString *s2 = @"foo";
    NSString *s3 = [[[NSString alloc] initWithString:@"foo"] autorelease];
    NSMutableString *s4 = [NSMutableString stringWithString:@"foobar"];
    [s4 replaceOccurrencesOfString:@"bar"
                        withString:@""
                           options:NSLiteralSearch
                             range:NSMakeRange(0, [s4 length])];

    NSLog(@"s1 = %p\n", s1);
    NSLog(@"s2 = %p\n", s2);
    NSLog(@"s3 = %p\n", s3);
    NSLog(@"s4 = %p\n", s4); // distinct from s1

    NSLog(@"%i", [s1 isEqualToString:s4]); // 1

    [pool release];

An example demonstrating how address comparison as a surrogate for string comparison will break:

    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    NSString *s1 = @"foo";
    NSString *s2 = @"foo";
    NSString *s3 = [[[NSString alloc] initWithString:@"foo"] autorelease];
    NSMutableString *s4 = [NSMutableString stringWithString:@"foobar"];
    [s4 replaceOccurrencesOfString:@"bar"
                        withString:@""
                           options:NSLiteralSearch
                             range:NSMakeRange(0, [s4 length])];

    NSLog(@"s1 = %p\n", s1);
    NSLog(@"s2 = %p\n", s2);
    NSLog(@"s3 = %p\n", s3);
    NSLog(@"s4 = %p\n", s4); // distinct from s1

    NSLog(@"%i", [s1 isEqualToString:s4]); // 1

    [pool release];
倾城泪 2024-09-25 19:02:04

在 Cocoa 中,字符串是使用 NSString 的 isEqualToString: 方法进行比较的。

指针比较适用于您的情况,因为编译器足够温和,可以合并两个字符串文字以指向一个对象。无法保证两个相同的字符串共享一个 NSString 实例。

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.

时光与爱终年不遇 2024-09-25 19:02:00

== 比较内存中的位置。 ptr == ptr2 如果它们都指向同一内存位置。这恰好适用于字符串常量,因为编译器恰好使用一个实际字符串来表示相同的字符串常量。如果您有具有相同内容的变量,则它不会工作,因为它们将指向不同的内存位置;在这种情况下使用 isEqualToString 。

== 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.

乖乖 2024-09-25 19:01:58

相等运算符 == 仅比较指针地址。当您使用文字 @"" 语法创建两个相同的字符串时,编译器将检测它们是否相等,并且仅存储数据一次。因此,两个指针指向同一个位置。然而,通过其他方式创建的字符串可能包含相同的数据,但存储在不同的内存位置。因此,在比较字符串时,您应该始终使用isEqual:

请注意,isEqual:isEqualToString: 始终返回相同的值,但 isEqualToString: 速度更快。

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.

紫瑟鸿黎 2024-09-25 19:01:55

== 起作用的原因是指针比较。当您使用 @"" 定义常量 NSString 时,编译器会唯一化引用。当在代码中的其他位置定义相同的常量时,它们都将指向内存中相同的实际位置。

比较 NSString 实例时,您应该使用 isEqualToString: 方法:

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
NSLog(@"%d", [myString1 isEqualToString:myString3]); //1
[myString3 release];

编辑:

NSString *myString3 = [[NSString alloc] initWithString:@"foo"]; 
// this is same with @"foo"

initWithString: 不再创建新引用,您将需要initWithFormat,

NSString *myString3 = [[NSString alloc] initWithFormat:@"foo"];

The reason why == works is because of pointer comparison. When you define a constant NSString using @"", the compiler uniquifies the reference. When the same constants are defined in other places in your code, they will all point to the same actual location in memory.

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
NSLog(@"%d", [myString1 isEqualToString:myString3]); //1
[myString3 release];

Edit:

NSString *myString3 = [[NSString alloc] initWithString:@"foo"]; 
// this is same with @"foo"

initWithString: does not create a new reference any more, you will need initWithFormat,

NSString *myString3 = [[NSString alloc] initWithFormat:@"foo"];
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文