2009-08-06 2 views
26

데이터베이스 모델 클래스가 NSObject입니다. 나는 NSMutableArray에이 객체들의 집합을 가지고 있습니다. 나는 indexOfObject:을 사용하여 일치하는 것을 찾습니다. 문제는 모델 객체의 메모리 주소가 변경된다는 것입니다. 그래서 hash 메서드를 재정 의하여 모델의 행 ID를 반환합니다. 그러나이 문제는 해결되지 않습니다. hash 메서드의 값을 비교하려면 isEqual: 메서드를 재정의해야합니다.NSObject isEqual : 및 hash default 함수는 무엇입니까?

isEqual: 메서드는 기본적으로 동등성을 결정하기 위해 어떤 방법을 사용합니까?

메모리 주소를 사용한다고 가정합니다. isEqual: 설명서를 읽은 후에 나는 hash 방법의 값을 사용한다고 생각했습니다. 분명히, 그 값을 무시하려는 나의 시도가 나의 초기 문제를 해결하지 못했기 때문에 그것은 사실이 아니다.

+0

여기에는 몇 가지 추측 해답이 있습니다. 누구든지 isEquals가 주소를 사용한다는 실제 문서를 제공 할 수 있습니까?> 나는 그것을 말하지 않고 있습니다. 그냥 말의 입에서 듣고 싶습니다. – DougW

+0

@DougW 나는 이것에 대해 당신의 감정을 공유했기 때문에 나는 공식적인 레퍼런스를 추적하고 그것을 수용된 대답으로 편집했다. –

+0

NSObject 클래스가 아닌 NSObject 프로토콜에 대한 문서를 읽는 중입니다. 프로토콜은 메소드가 수행해야하는 것을 정의하며, 클래스는 실제로 수행 할 작업을 정의하지 못합니다. equals 및 hash를 재정 의하여 항상 원하는 방식으로 작업하는 것이 가장 안전합니다. –

답변

26

정확하게 추측했듯이 NSObject의 기본값 인 isEqual:의 동작은 개체의 메모리 주소를 비교합니다. 이상하게도,이 현재, NSObject Class Reference 설명되어 있지 않습니다 있지만 내용의 Introspection 문서에 설명되어 있습니다 :

isEqual:의 기본 NSObject 구현은 포인터 어떤지를 확인합니다. 물론

, 당신은 의심 할 여지없이 알고있는대로, NSObject의 서브 클래스는 다르게 행동 isEqual:을 대체 할 수 있습니다. 예를 들어 NSStringisEqual: 메서드는 다른 NSString이 전달되면 먼저 주소를 확인한 다음 문자열 간의 정확한 리터럴 일치를 확인합니다.

+0

이것에 대한 참조는 좋을 것입니다. –

+1

... 그래서 하나 추가했습니다. 이상하게도,'NSObject' 클래스 레퍼런스는 isEqual :에 대한 항목조차 가지고 있지 않습니다. 어디서나 그 동작을 설명 할 뿐이지 만 눈에 띄는 누락처럼 보입니다. 그래도 문서의 '개념적'부분에있는 일부 모호한 페이지의 공식 참조를 추적 할 수있었습니다. –

+0

Apple 설명서에는 프로토콜 설명서가 클래스 설명서에 문서화되어 있지 않은 경우가 많이 있습니다. (수퍼 클래스 메서드는 말할 것도 없습니다.) 주어진 메서드에 대한 문서를 찾으려면 많은 바위 밑을 자주 살펴야합니다. –

4

NSObjectisEquals== 연산자를 사용하고 hash은 메모리 주소를 사용한다고 가정합니다.

isEquals 메서드는 절대로 절대 테스트로 hash을 사용해서는 안됩니다. 충분한 객체를 검색하는 경우 (두 개 이상의^32 개의 다른 객체를 만들고 두 개 이상이 동일한 hash을 가짐) 두 개의 객체가 비슷한 hashCode을 갖는 것이 보장됩니다.

즉, hash에는 다음과 같은 사양이 필요합니다. 두 개체가 같으면 해당 hash이 같아야합니다. 그러나 두 개의 객체 'hash 값이 같으면 반드시 같을 필요는 없습니다.

팁으로 항상 isEqualshashCode을 무시해야합니다.

+21

"나는"대답을 시작하는 것은 불행한 일이라고 생각합니다 ... –

8

isEqual:의 기본 구현에 대한 대답은 포괄적 인 답변입니다. 따라서 기본 구현 인 hash에 대한 메모를 추가하기 만하면됩니다. 여기있다 : 그것은 isEqual:에 사용되는 그냥 같은 포인터 값의

-(unsigned)hash {return (unsigned)self;} 

즉.여기에 당신이 이것을 확인하는 방법은 다음과 같습니다

obj: <NSObject: 0x16d44010> 
hash: 16d44010 

베스트 감사합니다 :

NSObject *obj = [[NSObject alloc] init]; 
NSLog(@"obj: %@",obj); 
NSLog(@"hash: %x",obj.hash); 

결과는 다음과 같이 될 것입니다.

iOS 8의 BTW hash은 메소드가 아니라 속성이되었습니다.하지만 거기에 있습니다.