To Implement KVC validattion method, override -(BOOL)validateIvar:error: or -validateValue:forKey:error:?
The former is described in the KVC Prog Guide, but missing from iOS API installed with Xcode 4.0.2 (with iOS 4.3 SDK) for Snow Leopard which lists the l开发者_如何学运维atter. This is for iOS 2.0 or newer. Thanks.
You can use both. For key named foo
, you can either implement a specific method
-(BOOL)validateFoo:(id*)ioValue error:(NSError**)error {
...
}
or, a non-specific method
- (BOOL)validateValue:(id *)ioValue forKey:(NSString *)key error:(NSError **)outError {
if([key isEqualToString:@"foo"]){
...
}else{
return [super validateValue:ioValue forKey:key error:outError];
}
}
It is perfectly sensible that you didn't find validateIvar:error:
in the API documentation, because the part Ivar
needs to be changed for each key. You don't find every method called setFoo:
for keys foo
you defined in the system API reference, do you?
You should only implement methods following the pattern validate<Key>:error:
(which can be done even in a category). Don't override validateValue:forKey:error:
, and do not call validateValue:forKey:error:
from within a validation method. You will cause an infinite loop. This is covered in the Key-Value Coding documentation and Core Data documentation, as well as within the Foundation headers. validateValue:forKey:error:
is the designated entry point into validation, both for Frameworks like CoreData and your applications.
Code that wishes to perform validation should invoke validateValue:forKey:error:
rather than the custom validation method directly.
For example:
if ([[self model] validateValue:&text forKey:@"name" error:&validationError]){
[[self model] setValue:text forKey:@"name"];
} else {
[self didFailWithError:validationError];
}
This should not be done from within an accessor method. An action method is the perfect place to do this.
A working example can be seen here
精彩评论