iOS - 객체 동일성
- (BOOL)isEqual:(id)obj {
return obj == self;
}
Foundation 프레임워크에서 일반적으로 NSObject의 하위 클래스는 다음과 같은 고유의 동일성 검사를 수행합니다.
대상이 같은지 아닌지를 비교하려면 간단하게 isEqual을 통해 대상을 비교하는 것이 아니라 상기 방법을 사용해서 비교하는 것을 권장합니다.
문자열
==로 문자열을 판단하지 마십시오. 코드는 다음과 같습니다.NSString *str1 = @"FlyElephant";
NSString *str2 = @"FlyElephant";
NSLog(@"%p---%p",str1,str2);
if (str1 == str2) {
NSLog(@" ");
}
의 코드는 우리가 기대하는 것은 같지 않지만 문자열이 머무르는 최적화 기술 때문에 모든 문자열은 하나의 공유 문자열 탱크에 있기 때문에 변하지 않는 문자열의 값을 서로 다른 지침에 부여한다.
isEqual
두 객체가 동일한지 비교하려면 특정 객체의 데이터를 기준으로 시스템 비교를 수행하여 Person 클래스를 구성하고 이름, 나이, 지역 세 필드를 정의해야 합니다.@interface Person : NSObject
@property (copy, nonatomic) NSString *name;
@property (assign, nonatomic) NSUInteger age;
@property (copy, nonatomic) NSString *location;
- (BOOL)isEqualToPerson:(Person *)person;
@end
- (BOOL)isEqualToPerson:(Person *)person {
if (!person) {
return NO;
}
BOOL isEqualName = (!self.name && !person.name) || [self.name isEqualToString:person.name];
BOOL isEqualAge = self.age == person.age;
BOOL isEqualLocation = (!self.location && !person.location) || [self.location isEqualToString:person.location];
return isEqualName & isEqualAge & isEqualLocation;
}
두 Person이 동일한지 비교하려면 isEqualPeron을 통해 비교합니다. Person *person1 = [[Person alloc] init];
person1.name = @"FlyElephant";
person1.age = 27;
person1.location = @" ";
Person *person2 = [[Person alloc] init];
person2.name = @"FlyElephant";
person2.age = 27;
person2.location = @" ";
BOOL isEqulPerson = [person1 isEqualToPerson:person2];
if (isEqulPerson) {
NSLog(@"person1 person2 ");
} else {
NSLog(@" ");
}
만약에 전달 대상이 자신이라면 이후의 판단을 할 필요가 없고 비교적 많은 비교 방법이 나타나지 않도록 isEqual 방법을 다시 쓰기 위해 isEqual ToPerson 방법을 그 안에 내장하면 된다.- (BOOL)isEqual:(id)object {
if (self == object) {
return YES;
}
if (![object isKindOfClass:[Person class]]) {
return NO;
}
return [self isEqualToPerson:(Person *)object];
}
isEqual을 통한 판단 결과는 isEqualPerson 결과와 일치합니다. BOOL isEqual = [person1 isEqualToPerson:person2];
if (isEqual) {
NSLog(@"isEqual:person1 person2 ");
} else {
NSLog(@"isEqual: ");
}
hash
대상을 비교하는 과정에서 만약에 두 대상이 같다면hash값은 반드시 같고 두 대상의hash값은 같으며 대상이 반드시 같지 않다는 것을 자주 들을 수 있다.
코드에서person1과person2를 비교하는 과정에서hash를 호출하지 않았습니다. 그러면 대상의hash방법을 언제 호출합니까?- (NSUInteger)hash {
NSUInteger hash = [super hash];
NSLog(@"Person hash = %ld", hash);
return hash;
}
Objective-C 컬렉션 클래스, NSMutable Array, NSMutable Set, NSMutable Dictonary를 통해 Person 객체를 추가합니다. Person *person1 = [[Person alloc] init];
person1.name = @"FlyElephant";
person1.age = 27;
person1.location = @" ";
Person *person2 = [[Person alloc] init];
person2.name = @"FlyElephant1";
person2.age = 28;
person2.location = @" ";
NSMutableArray *arr1 = [[NSMutableArray alloc] initWithObjects:person1, nil];
NSMutableArray *arr2 = [[NSMutableArray alloc] initWithObjects:person2, nil];
NSLog(@" ----------------------");
NSMutableSet *set1 = [NSMutableSet set];
[set1 addObject:person1];
NSMutableSet *set2 = [NSMutableSet set];
[set2 addObject:person2];
NSLog(@"NSMutableSet -------------------------------");
NSMutableDictionary *dictionaryValue1 = [NSMutableDictionary dictionary];
[dictionaryValue1 setObject:person1 forKey:@"dic1"];
NSMutableDictionary *dictionaryValue2 = [NSMutableDictionary dictionary];
[dictionaryValue2 setObject:person2 forKey:@"dic2"];
NSLog(@"dictionary person -------------------------------");
NSMutableDictionary *dictionaryKey1 = [NSMutableDictionary dictionary];
[dictionaryKey1 setObject:@"1" forKey:person1];
NSMutableDictionary *dictionaryKey2 = [NSMutableDictionary dictionary];
[dictionaryKey2 setObject:@"2" forKey:person2];
NSLog(@"dictionary person -------------------------------");
----------------------
Person hash = 106102872298336
Person hash = 106102872298336
Person hash = 106102872298432
Person hash = 106102872298432
NSMutableSet -------------------------------
dictionary person -------------------------------
Person hash = 106102872298336
Person hash = 106102872298496
Person hash = 106102872298432
Person hash = 106102872298528
dictionary person -------------------------------
Person이 사전의 키 값으로 설정된 경우 NSCopying 프로토콜이 필요합니다.- (id)copyWithZone:(NSZone *)zone {
Person *model = [[[self class] allocWithZone:zone] init];
model.name = self.name;
model.age = self.age;
model.location = self.location;
return model;
}
해시 테이블(Hash Table)은 프로그램 설계의 기초적인 데이터 구조 중 하나로 NSSet과 NSDictionary가 원소를 매우 빠르게 찾을 수 있도록 한다.
수조 중의 원소가 메모리에 분포하는 것은 연속적인 주소이기 때문에 어떤 원소가 존재하는지 판단할 필요가 있으면 점차적으로 훑어보아야 한다.
산열표는 산열 함수를 통해 산열 값을 계산하여 원소의 고른 분포를 실현하고 서로 다른 원소가 같은 산열 값이 나타나면 산열 충돌이 발생한다.산열 목록 역시 원소의 산열 값을 통해 원소를 빨리 찾을 수 있다.
NSSet은 원소의 산열 값에 따라 원소의 중복을 판단한다. NSDictionary에서 키는 중복될 수 없다. 모든 원소의 산열 값이 유일해야 하며 이 두 집합은 대상의hash 방법을 호출한다.
서로 다른 원소의hash방법실현은 서로 다른 방식이 있을 수 있다. 만약에 시간대상이라면hash실현은 다음과 같다.- (NSUInteger)hash {
return (NSUInteger)abs([self timeIntervalSinceReferenceDate]);
}
UIColor 객체의 경우 변위를 통해 다음을 수행할 수 있습니다.- (NSUInteger)hash {
CGFloat red, green, blue;
[self getRed:&red green:&green blue:&blue alpha:nil];
return ((NSUInteger)(red * 255) << 16) + ((NSUInteger)(green * 255) << 8) + (NSUInteger)(blue * 255);
}
대신Matt Thompson의 조언: 대부분의 경우 우리는 관건적인 속성의 산열값에 대해 간단한 이소(XOR) 조작만 하면 99퍼센트의 상황에서 수요를 만족시킬 수 있다.- (NSUInteger)hash {
return [self.name hash] ^ [self.location hash];
}
참고 링크: iOS-is Equal, is Equal To String과 == equality iOS 개발을 구별하는 것은 나에게 네가 정말 is Equal과hash를 안다고 말하지 마라!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSON
JSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다.
그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다.
저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.
NSString *str1 = @"FlyElephant";
NSString *str2 = @"FlyElephant";
NSLog(@"%p---%p",str1,str2);
if (str1 == str2) {
NSLog(@" ");
}
두 객체가 동일한지 비교하려면 특정 객체의 데이터를 기준으로 시스템 비교를 수행하여 Person 클래스를 구성하고 이름, 나이, 지역 세 필드를 정의해야 합니다.
@interface Person : NSObject
@property (copy, nonatomic) NSString *name;
@property (assign, nonatomic) NSUInteger age;
@property (copy, nonatomic) NSString *location;
- (BOOL)isEqualToPerson:(Person *)person;
@end
- (BOOL)isEqualToPerson:(Person *)person {
if (!person) {
return NO;
}
BOOL isEqualName = (!self.name && !person.name) || [self.name isEqualToString:person.name];
BOOL isEqualAge = self.age == person.age;
BOOL isEqualLocation = (!self.location && !person.location) || [self.location isEqualToString:person.location];
return isEqualName & isEqualAge & isEqualLocation;
}
두 Person이 동일한지 비교하려면 isEqualPeron을 통해 비교합니다.
Person *person1 = [[Person alloc] init];
person1.name = @"FlyElephant";
person1.age = 27;
person1.location = @" ";
Person *person2 = [[Person alloc] init];
person2.name = @"FlyElephant";
person2.age = 27;
person2.location = @" ";
BOOL isEqulPerson = [person1 isEqualToPerson:person2];
if (isEqulPerson) {
NSLog(@"person1 person2 ");
} else {
NSLog(@" ");
}
만약에 전달 대상이 자신이라면 이후의 판단을 할 필요가 없고 비교적 많은 비교 방법이 나타나지 않도록 isEqual 방법을 다시 쓰기 위해 isEqual ToPerson 방법을 그 안에 내장하면 된다.
- (BOOL)isEqual:(id)object {
if (self == object) {
return YES;
}
if (![object isKindOfClass:[Person class]]) {
return NO;
}
return [self isEqualToPerson:(Person *)object];
}
isEqual을 통한 판단 결과는 isEqualPerson 결과와 일치합니다.
BOOL isEqual = [person1 isEqualToPerson:person2];
if (isEqual) {
NSLog(@"isEqual:person1 person2 ");
} else {
NSLog(@"isEqual: ");
}
hash
대상을 비교하는 과정에서 만약에 두 대상이 같다면hash값은 반드시 같고 두 대상의hash값은 같으며 대상이 반드시 같지 않다는 것을 자주 들을 수 있다.
코드에서person1과person2를 비교하는 과정에서hash를 호출하지 않았습니다. 그러면 대상의hash방법을 언제 호출합니까?- (NSUInteger)hash {
NSUInteger hash = [super hash];
NSLog(@"Person hash = %ld", hash);
return hash;
}
Objective-C 컬렉션 클래스, NSMutable Array, NSMutable Set, NSMutable Dictonary를 통해 Person 객체를 추가합니다. Person *person1 = [[Person alloc] init];
person1.name = @"FlyElephant";
person1.age = 27;
person1.location = @" ";
Person *person2 = [[Person alloc] init];
person2.name = @"FlyElephant1";
person2.age = 28;
person2.location = @" ";
NSMutableArray *arr1 = [[NSMutableArray alloc] initWithObjects:person1, nil];
NSMutableArray *arr2 = [[NSMutableArray alloc] initWithObjects:person2, nil];
NSLog(@" ----------------------");
NSMutableSet *set1 = [NSMutableSet set];
[set1 addObject:person1];
NSMutableSet *set2 = [NSMutableSet set];
[set2 addObject:person2];
NSLog(@"NSMutableSet -------------------------------");
NSMutableDictionary *dictionaryValue1 = [NSMutableDictionary dictionary];
[dictionaryValue1 setObject:person1 forKey:@"dic1"];
NSMutableDictionary *dictionaryValue2 = [NSMutableDictionary dictionary];
[dictionaryValue2 setObject:person2 forKey:@"dic2"];
NSLog(@"dictionary person -------------------------------");
NSMutableDictionary *dictionaryKey1 = [NSMutableDictionary dictionary];
[dictionaryKey1 setObject:@"1" forKey:person1];
NSMutableDictionary *dictionaryKey2 = [NSMutableDictionary dictionary];
[dictionaryKey2 setObject:@"2" forKey:person2];
NSLog(@"dictionary person -------------------------------");
----------------------
Person hash = 106102872298336
Person hash = 106102872298336
Person hash = 106102872298432
Person hash = 106102872298432
NSMutableSet -------------------------------
dictionary person -------------------------------
Person hash = 106102872298336
Person hash = 106102872298496
Person hash = 106102872298432
Person hash = 106102872298528
dictionary person -------------------------------
Person이 사전의 키 값으로 설정된 경우 NSCopying 프로토콜이 필요합니다.- (id)copyWithZone:(NSZone *)zone {
Person *model = [[[self class] allocWithZone:zone] init];
model.name = self.name;
model.age = self.age;
model.location = self.location;
return model;
}
해시 테이블(Hash Table)은 프로그램 설계의 기초적인 데이터 구조 중 하나로 NSSet과 NSDictionary가 원소를 매우 빠르게 찾을 수 있도록 한다.
수조 중의 원소가 메모리에 분포하는 것은 연속적인 주소이기 때문에 어떤 원소가 존재하는지 판단할 필요가 있으면 점차적으로 훑어보아야 한다.
산열표는 산열 함수를 통해 산열 값을 계산하여 원소의 고른 분포를 실현하고 서로 다른 원소가 같은 산열 값이 나타나면 산열 충돌이 발생한다.산열 목록 역시 원소의 산열 값을 통해 원소를 빨리 찾을 수 있다.
NSSet은 원소의 산열 값에 따라 원소의 중복을 판단한다. NSDictionary에서 키는 중복될 수 없다. 모든 원소의 산열 값이 유일해야 하며 이 두 집합은 대상의hash 방법을 호출한다.
서로 다른 원소의hash방법실현은 서로 다른 방식이 있을 수 있다. 만약에 시간대상이라면hash실현은 다음과 같다.- (NSUInteger)hash {
return (NSUInteger)abs([self timeIntervalSinceReferenceDate]);
}
UIColor 객체의 경우 변위를 통해 다음을 수행할 수 있습니다.- (NSUInteger)hash {
CGFloat red, green, blue;
[self getRed:&red green:&green blue:&blue alpha:nil];
return ((NSUInteger)(red * 255) << 16) + ((NSUInteger)(green * 255) << 8) + (NSUInteger)(blue * 255);
}
대신Matt Thompson의 조언: 대부분의 경우 우리는 관건적인 속성의 산열값에 대해 간단한 이소(XOR) 조작만 하면 99퍼센트의 상황에서 수요를 만족시킬 수 있다.- (NSUInteger)hash {
return [self.name hash] ^ [self.location hash];
}
참고 링크: iOS-is Equal, is Equal To String과 == equality iOS 개발을 구별하는 것은 나에게 네가 정말 is Equal과hash를 안다고 말하지 마라!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSON
JSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다.
그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다.
저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.
- (NSUInteger)hash {
NSUInteger hash = [super hash];
NSLog(@"Person hash = %ld", hash);
return hash;
}
Person *person1 = [[Person alloc] init];
person1.name = @"FlyElephant";
person1.age = 27;
person1.location = @" ";
Person *person2 = [[Person alloc] init];
person2.name = @"FlyElephant1";
person2.age = 28;
person2.location = @" ";
NSMutableArray *arr1 = [[NSMutableArray alloc] initWithObjects:person1, nil];
NSMutableArray *arr2 = [[NSMutableArray alloc] initWithObjects:person2, nil];
NSLog(@" ----------------------");
NSMutableSet *set1 = [NSMutableSet set];
[set1 addObject:person1];
NSMutableSet *set2 = [NSMutableSet set];
[set2 addObject:person2];
NSLog(@"NSMutableSet -------------------------------");
NSMutableDictionary *dictionaryValue1 = [NSMutableDictionary dictionary];
[dictionaryValue1 setObject:person1 forKey:@"dic1"];
NSMutableDictionary *dictionaryValue2 = [NSMutableDictionary dictionary];
[dictionaryValue2 setObject:person2 forKey:@"dic2"];
NSLog(@"dictionary person -------------------------------");
NSMutableDictionary *dictionaryKey1 = [NSMutableDictionary dictionary];
[dictionaryKey1 setObject:@"1" forKey:person1];
NSMutableDictionary *dictionaryKey2 = [NSMutableDictionary dictionary];
[dictionaryKey2 setObject:@"2" forKey:person2];
NSLog(@"dictionary person -------------------------------");
----------------------
Person hash = 106102872298336
Person hash = 106102872298336
Person hash = 106102872298432
Person hash = 106102872298432
NSMutableSet -------------------------------
dictionary person -------------------------------
Person hash = 106102872298336
Person hash = 106102872298496
Person hash = 106102872298432
Person hash = 106102872298528
dictionary person -------------------------------
- (id)copyWithZone:(NSZone *)zone {
Person *model = [[[self class] allocWithZone:zone] init];
model.name = self.name;
model.age = self.age;
model.location = self.location;
return model;
}
- (NSUInteger)hash {
return (NSUInteger)abs([self timeIntervalSinceReferenceDate]);
}
- (NSUInteger)hash {
CGFloat red, green, blue;
[self getRed:&red green:&green blue:&blue alpha:nil];
return ((NSUInteger)(red * 255) << 16) + ((NSUInteger)(green * 255) << 8) + (NSUInteger)(blue * 255);
}
- (NSUInteger)hash {
return [self.name hash] ^ [self.location hash];
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.