There is a standard validation pattern in Cocoa, including Cocoa Touch, called Key-Value Validation that you should conform to if you want to validate user input other than through an NSFormatter.
In essence, for a property name
that you want validated, you implement a method following this pattern:
- (BOOL)validateName:(id *)ioValue error:(NSError **)error;
Then, when you want to validate a property before setting it from your UI, you just use:
NSString *proposedName = [[nameField.stringValue copy] autorelease];
NSError *nameError;
if ([person validateValue:&proposedName forKey:@"name" error:&nameError]) {
person.name = proposedName;
} else {
// present nameError to the user in a reasonable way
}
Note that you do not invoke -validateValue:forKey:error:
or -validateName:error:
method in your -setName:
method. Instead, you invoke your -setName:
method (as I do via dot syntax above) once you know the value you're passing for it will be valid.
Also, read the document on Key-Value Validation that I mentioned above to understand why proposedName
is an autoreleased copy of a field's string value, instead of just its string value.
If you're implementing something more complicated than per-property validation, such as whole-object validation or even object graph validation, be sure to see how the Core Data framework on Mac OS X handles it.