Понимание сравнения NSString - PullRequest
       15

Понимание сравнения NSString

82 голосов
/ 13 сентября 2010

Оба следующих сравнения оценивают как истинные:

1)

@"foo" == @"foo";

2)

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

Однако, безусловно, бывают случаи, когда два NSStrings нельзя сравнивать с помощью оператора равенства, вместо этого требуется [myString1 isEqualToString:myString2].Может кто-нибудь пролить свет на это?

Ответы [ 7 ]

162 голосов
/ 13 сентября 2010

Причина, по которой работает ==, заключается в сравнении указателей.Когда вы определяете константу 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"];
13 голосов
/ 13 сентября 2010

Оператор равенства == сравнивает только адреса указателей. Когда вы создаете две одинаковые строки, используя буквальный синтаксис @"", компилятор обнаружит, что они равны, и сохранит данные только один раз. Следовательно, два указателя указывают на одно и то же местоположение. Однако строки, созданные другими средствами, могут содержать идентичные данные, но храниться в разных местах памяти. Следовательно, всегда следует использовать isEqual: при сравнении строк.

Обратите внимание, что isEqual: и isEqualToString: всегда возвращают одно и то же значение, но isEqualToString: быстрее.

10 голосов
/ 13 сентября 2010

== сравнивает места в памяти. ptr == ptr2, если они оба указывают на одну и ту же ячейку памяти. Это работает с строковыми константами, потому что компилятор использует одну фактическую строку для идентичных строковых констант не будет работать, если у вас есть переменные с одинаковым содержимым, потому что они будут указывать на разные области памяти; используйте isEqualToString в таком случае.

6 голосов
/ 13 сентября 2010

В строках Какао сравниваются с помощью метода NSString isEqualToString:.

Сравнение указателей работает в вашем случае, потому что компилятор достаточно мягкий, чтобы объединить два строковых литерала для указания на один объект. Нет гарантии, что две идентичные строки совместно используют один NSString экземпляр.

3 голосов
/ 17 января 2012

Пример, демонстрирующий, как сравнение адресов как суррогат для сравнения строк прекратится:

    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 голосов
/ 05 мая 2017
  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 голосов
/ 17 апреля 2017

Проверьте этот пример:

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 для обработки isEquals для указателей NSString и разыменования, хотя этого не требовалось. И указатели разные, как вы видите.

...