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


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

1)

@"foo" == @"foo";

2)

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

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

7 80

7 ответов:

почему == работает из-за сравнения указатель. Когда вы определяете константу 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];

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

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

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

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

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

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

    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];

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

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

  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");

    }