Objective-C의 객체 동일성 판정 방법

Objective-C의 객체 동일성 판정 방법
'등동성'에 따라 대상을 비교하는 것은 매우 유용한 기능이다.그러나 ==조작부호를 통해 비교한 결과가 반드시 우리가 원하는 것은 아니다. 왜냐하면 이 조작이 비교한 것은 두 개의 바늘 자체이지 가리키는 대상이 아니기 때문이다.NSObject 프로토콜에 명시된 "isEqual:"방법을 사용하여 두 객체의 동일성을 결정해야 합니다.일반적으로 두 유형의 서로 다른 대상은 항상 같지 않다.일부 대상 대상은 특수한'등동성 판정 방법'을 제공하는데, 두 측정 대상이 모두 같은 종류에 속한다는 것을 이미 알고 있다면 이런 방법을 사용할 수 있다.다음 코드를 예로 들면 다음과 같습니다.
NSString *foo = @"Badger 123";
NSString *bar = [NSString stringWithFormat:@"Badger %i",123];
BOOL equalA = (foo == bar);// NO
BOOL equalB = [foo isEqual:bar];//YES
BOOL equalC = [foo isEqualToString:bar];//YES

등동성 판정 방법과의 차이를 볼 수 있다.NSString 클래스는'isEqual ToString:'이라는 자신만의 등동성 판정 방법을 실현했다.메서드에 전달되는 객체는 NSString이어야 하며 그렇지 않으면 결과가 정의되지 않습니다.이 방법은 isEqual을 호출하는 것보다 빠르다. 후자는 측정 대상의 유형을 판단하기 위해 추가 절차를 수행해야 하기 때문이다.NSObject 프로토콜에는 다음과 같은 두 가지 주요 메서드가 있습니다.
- (BOOL)isEqual:(id)object; - (NSUInteger)hash;

NSObject 클래스는 두 메서드에 대해 기본적으로 "포인터 지정"이 완전히 같아야 두 객체가 동일합니다.사용자 정의 대상에서 이 방법을 정확하게 복기하려면 그 약속을 먼저 이해해야 한다.만약 "isEqual:"방법이 두 대상을 동일하게 판정한다면,hash 방법은 같은 값을 되돌려야 합니다.그러나 만약 두 대상의hash방법이 같은 값을 되돌려준다면'isEqual:'방법은 반드시 둘이 같다고 생각하지 않을 것이다.예를 들어 다음과 같은 종류가 있다.
@interface EOCPerson : NSObject
@property (nonatomic, copy) NSString *firstName;
@property (nonatomic, copy) NSString *lastName;
@property (nonatomic, assign) NSUInteger age;
@end

일반적으로 두 EOCPerson의 모든 필드가 같으면 이 두 대상은 같다고 여긴다.그래서'isEqual:'방법은 다음과 같다.
- (BOOL)isEqual:(id)object {
    if (self == object) return YES;// 1.             
    if ([self class] != [object class]) return NO;//2.          
    EOCPerson *otherPerson = (EOCPerson *)object;
    if (![_lastName isEqualToString:otherPerson.lastName]) return NO;
    if (_age != otherPerson.age) return NO;//3.        
    return YES;
}

4
  • 우선 두 지침이 동일한지 직접 판단한다.만약 같다면 모두 같은 대상을 가리키기 때문에 측정된 대상도 반드시 같다

  • 4
  • 두 종류가 속한 종류를 비교한다.같은 클래스에 속하지 않으면 두 대상은 같지 않다.그러나 때때로 우리는 부류 실례가 부류 실례와 같을 수 있다고 생각할 수도 있다.상속 체계에서 등동성을 판단할 때 이런 문제가 자주 발생한다.그래서 "isEqual:"방법을 실현할 때 이런 상황을 고려해야 한다

  • 4
  • 각 속성이 동일한지 확인합니다.그중에 서로 다른 속성이 있으면 이 두 대상이 서로 같지 않다고 판정한다. 그렇지 않으면 두 대상이 서로 같다

  • 4
  • hash방법을 실현한다.등동성 약정에 따르면 두 대상이 같으면 그 해시 코드도 같지만 두 해시 코드가 같은 대상은 반드시 같지 않다.이것은 "isEqual:"방법을 정확하게 복사할 수 있는지의 관건이다.해시 방법의 실현: 같은 해시 코드로 돌아가는 것은 가능하지만 취할 수 없다.만약 같은 해시 코드를 되돌려준다면, 집합에서 이런 대상을 사용하면 성능 문제가 발생할 것이다.집합에서 대상을 검색할 때 대상의 해시 코드를 색인으로 사용하기 때문에 검색 효율은 다음과 같은 비교적 좋은 방법을 추천합니다
  • - (NSUInteger)hash {
        NSUInteger firstNameHash = [_firstName hash];
        NSUInteger lastNameHash = [_lastName hash];
        NSUInteger ageHash = _age;
        return firstNameHash ^ lastNameHash ^ ageHash;
    }

    이런 방법은 해시 코드 생성의 효율을 보장할 수 있다.또한 생성된 해시 코드를 최소한 일정한 범위 내에 두어 충돌 횟수를 줄일 수 있다.
    특정 클래스가 가지고 있는 등동성 판정 방법 시스템 중 일부 클래스의 등동성 판정 방법: NSString, 등동성 판정 방법: isEqual ToString: NSArray, 등동성 판정 방법: isEqual ToArray: NSDictionary: 등동성 판정 방법: isEqual ToDictionary: 이런 방법들이 측정 대상의 유형이 정확하지 않으면 이상을 던질 수 있다.사용자 정의 클래스의 판정 방법을 작성할 때도'isEqual:'방법을 함께 덮어써야 한다.흔히 볼 수 있는 실현 방식은 측정된 대상과 메시지를 받는 대상이 모두 같은 클래스에 속한다면 자신이 작성한 판정 방법을 사용하고 그렇지 않으면 부류에 의해 판정하는 것이다.다음과 같은 코드가 구현됩니다.
    - (BOOL)isEqualToPerson:(EOCPerson *)otherPerson {
        if (self == otherPerson) return YES;
        if (![_firstName isEqualToString:otherPerson.firstName]) {
            return NO;
        }
        if (![_lastName isEqualToString:otherPerson.lastName]) {
            return NO;
        }
        if (_age != otherPerson.age) {
            return NO;
        }
        return YES;
    }
    
    - (BOOL)isEqual:(id)object {
        if ([self class] == [object class]) {
            return [self isEqualToPerson:(EOCPerson *)object];
        } else {
            return [super isEqual:object];
        }
    }
    

    등동성 판정의 집행 깊이 창설 등 동성 판정 방법은 전체 대상에 따라 등동성을 판단할 것인지, 아니면 그 중 몇 개의 필드에만 따라 판단할 것인지를 결정해야 한다.깊이 등동성 판정: NSArray의 경우 NSArray 검측 방식은 두 그룹이 포함하는 대상의 개수가 같은지 먼저 보고, 같으면 대응하는 위치의 두 대상에게'isEqual:'방법을 호출한다.만약 대응하는 위치의 대상이 모두 같다면, 이 두 수조는 서로 같다.그러나 때로는 모든 데이터를 하나하나 비교할 필요가 없다.객체에 고유한 식별자가 있는 경우 일부 데이터만 기준으로 판정할 수 있습니다.
    용기 중의 가변류의 등동성은 용기에 가변류 대상을 넣을 때 어떤 대상을 집합에 넣은 후에 해시 코드를 바꾸지 말아야 한다.집합은 각 대상의 해시 코드에 따라 데이터를 서로 다른 위치에 분장할 것이다. 만약에 어떤 대상이 수조에 넣은 후에 해시 코드가 또 변한다면 현재 있는 수조는 이 대상에게 잘못된 것이다.더 구체적인 소개는 참고서인 에서 제8조의 소개를 참고하십시오.주요 사항 요약: 1.객체의 등동성을 체크하려면 "isEqual:"및 hash 메서드를 제공합니다.2. 같은 대상은 반드시 같은 해시 코드를 가지고 있어야 하지만 두 개의 해시 코드가 같은 대상은 반드시 같지 않다.3. 모든 속성을 맹목적으로 하나하나 검측하지 말고 구체적인 수요에 따라 검측 방안을 맞춤형으로 만들어야 한다.4.hash방법을 작성할 때 계산 속도가 빠르고 해시코드가 충돌할 확률이 낮은 알고리즘을 사용해야 한다.
    참고: Effective Objective-C 2.0에서 고품질 iOS와 OS X 코드를 작성하는 52가지 유효한 방법에 따라 발췌 및 정리합니다.

    좋은 웹페이지 즐겨찾기