Understanding NSString comparison

后端 未结 7 1621
情歌与酒
情歌与酒 2020-11-22 12:15

Both the following comparisons evaluate to true:

1)

@\"foo\" == @\"foo\";

2)

NSString *myString1 = @\"foo\";
NSStri         


        
相关标签:
7条回答
  • 2020-11-22 12:53

    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.

    0 讨论(0)
  • 2020-11-22 12:56

    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.

    0 讨论(0)
  • 2020-11-22 13:02

    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"];
    
    0 讨论(0)
  • 2020-11-22 13:05
      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");
    
        }
    
    0 讨论(0)
  • 2020-11-22 13:08

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

    0 讨论(0)
  • 2020-11-22 13:09

    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];
    
    0 讨论(0)
提交回复
热议问题