티스토리 뷰
Swift & objc
Key-Value Coding Programming Guide - Adopting Key-Value Coding - Adding Validation
rhinoPHS 2019. 2. 3. 13:47Key-Value Coding Programming Guide - Adopting Key-Value Coding - Adding Validation
KVC 프로토콜은 key나 keypath에 대해서 검증하는 메소드를 가지고 있습니다. 이 메소드들의 기본 구현은 접근자 메소드와 비슷하게 naming patterns을 따릅니다. validate<Key>:error: 메소드를 사용해서 key값을 검증합니다. validateValue:forKey:error:메시지에 반응해서 동작합니다.
프로퍼티에 대한 검증 메소드를 만들지 않으면, 기본적으로 값에 상관없이 유효하다고 판단합니다.
!Note
이 문서를 objc 에만 해당합니다. swift에서는 컴파일러가 알아서 해주는데 , 더 자세한 정보는 The Swift programming languge문서에 property observes를 참조하면 됩니다.
Implementing a Validation Method
프로퍼티 검증 메소드는 2개의 파타미터를 참조로 받습니다. 검증할 객체와 error정보를 리턴하는데 사용하는 NSError에 대한 참조 입니다. 다음 중 하나로 동작합니다.
동작1. 객체가 유효하면 YES를 리턴하고 value객체나 error는 변화 없습니다.
동작2. 객체가 유효하지 않는 경우, 유효한 객체로 대체 할 수 없다면 error에 정보를 담고 NO를 리턴합니다.
에러 정보를 담을 때는 NULL이 아닌지 확인해야 합니다.
동작3. 객체가 유효하지 않다면, 유요한 객체로 대체할 수 있습니다. 그리고 에러없이 YES를 리턴합니다. 대체할 때 원본객체가 변경 가능하하더라도 수정하지 않고 대체합니다.
다음 예제는 name에 대해 검증합니다. 객체가 nil이 아닌지 확인하고 문자열 길이가 최소값보다 작은지 확인합니다. 이 메소는 객체가 유요하지 않을 때 다른 값으로 대체하지 않습니다.
- (BOOL)validateName:(id *)ioValue error:(NSError * __autoreleasing *)outError{
if ((*ioValue == nil) || ([(NSString *)*ioValue length] < 2)) {
if (outError != NULL) {
*outError = [NSError errorWithDomain:PersonErrorDomain
code:PersonInvalidNameCode
userInfo:@{ NSLocalizedDescriptionKey
: @"Name too short" }];
}
return NO;
}
return YES;
}
Validation of Scalar Values
검증 메소드는 객체를 받기 때문에 객체가 아닌 스칼라나 구조체에 대해서는 NSValue나 NSNumber객체로 wrapping합니다. 아래 예제는 age라는 스칼라 값에 대해 검증합니다. 유효하지 않는 경우로는 age가 nil인데,
이 경우에 NSNumber에 0을 넣어 wrapping한 후 YES를 리턴합니다.
이 경우에는 또 클래스 호출하는 쪽에서 유효성 검사 메소드를 호출하지 않을 수도 있어서 setNilValueForKey:를 오버라이드 해서 처리 할 수 도 있습니다.
Listing 11-2Validation method for a scalar property
- (BOOL)validateAge:(id *)ioValue error:(NSError * __autoreleasing *)outError {
if (*ioValue == nil) {
// Value is nil: Might also handle in setNilValueForKey
*ioValue = @(0);
} else if ([*ioValue floatValue] < 0.0) {
if (outError != NULL) {
*outError = [NSError errorWithDomain:PersonErrorDomain
code:PersonInvalidAgeCode
userInfo:@{ NSLocalizedDescriptionKey
: @"Age cannot be negative" }];
}
return NO;
}
return YES;
}