Question

I was reading Apple's Introductory guidelines which encourage developers to use NSErrors instead of throwing exceptions.

In this case, I'm a bit confused about how to validate data that is passed in to a setter. For example, say you have a setAge: method; how would you validate that the age entered is greater than 0? Would you simply let the program run with the invalid age?

Was it helpful?

Solution 2

Either an assertion (since the caller should have validated) or an exception (ditto) or just ignore the problem. A setter simulates simple assignment to a variable and so is not expected to perform formal validation. Or you can implement a separate setValue:error: method (which can't be used with dot assignment notation) and mark the var read-only in the @property statement.

You should not set the value into the property until after it's been validated by the method calling the "set" method. Any checking in the "set" method is purely for bug detection.

OTHER TIPS

Usually you would make sure that what ever controller sets the age of your model object validates the value. For instance if the user is asked to specify an age, the view controller would parse the input, validate it, and then pass it to the appropriate model object.

Alternatively, you can implement Key-Value Validation in your model object. Take a look at the last section, which happens to be exactly your example:

- (BOOL)validateAge:(id *)ioValue error:(NSError * __autoreleasing *)outError {

    if (*ioValue == nil) {
        // Trap this in setNilValueForKey.
        // An alternative might be to create new NSNumber with value 0 here.
        return YES;
    }
    if ([*ioValue floatValue] <= 0.0) {
        if (outError != NULL) {
            NSString *errorString = NSLocalizedStringFromTable(
                @"Age must be greater than zero", @"Person",
                @"validation: zero age error");
            NSDictionary *userInfoDict = @{ NSLocalizedDescriptionKey : errorString };
            NSError *error = [[NSError alloc] initWithDomain:PERSON_ERROR_DOMAIN
                code:PERSON_INVALID_AGE_CODE
                userInfo:userInfoDict];
            *outError = error;
        }
        return NO;
    }
    else {
        return YES;
    }
    // ...
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top