[objective-c] NSString 비교 이해

다음 비교는 모두 참으로 평가됩니다.

1)

@"foo" == @"foo";

2)

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

그러나 NSString항등 연산자를 사용하여 두 s를 비교할 수없는 경우가 있으며 [myString1 isEqualToString:myString2]대신 필요합니다. 누군가 이것에 대해 밝힐 수 있습니까?



답변

이유 ==일 때문에 포인터 비교입니다. 를 사용하여 상수 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"];


답변

항등 연산자 ==는 포인터 주소 만 비교합니다. 리터럴 @""구문을 사용하여 두 개의 동일한 문자열을 만들면 컴파일러는 두 문자열 이 같은지 감지하고 데이터를 한 번만 저장합니다. 따라서 두 포인터는 동일한 위치를 가리 킵니다. 그러나 다른 방법으로 생성 된 문자열은 동일한 데이터를 포함 할 수 있지만 다른 메모리 위치에 저장됩니다. 따라서 문자열을 비교할 때 항상 사용해야 isEqual:합니다.

참고 isEqual:isEqualToString:항상 같은 값을 반환하지만 isEqualToString:더 빠릅니다.


답변

==메모리의 위치를 ​​비교합니다. ptr == ptr2둘 다 동일한 메모리 위치를 가리키는 경우. 이것은 컴파일러가 동일한 문자열 상수에 대해 하나의 실제 문자열 을 사용하기 때문에 문자열 상수와 함께 작동 합니다. 그것은 하지 않습니다 당신이 같은 내용 변수가있는 경우 서로 다른 메모리 위치를 가리키는 것이기 때문에, 작동; 사용 isEqualToString등의 경우이다.


답변

Cocoa에서 문자열은 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 메서드를 사용하여 NSString 및 역 참조 포인터에 대해 isEquals를 처리 할 가능성이 높습니다. 보시다시피 포인터가 다릅니다.


답변

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

    }