André Fratelli
André Fratelli

Reputation: 6068

Initialising a category in objective-c

I'm writing a category for UITextField to include validation. I wish to change the text field's visual according to validation state (such as having an approved icon as its right view). For this, I keep a validation state property and wish to update the visual on its setter.

Here's what I have (UITextField+Validation.h)

@interface UITextField (Validation)

// Validator registration
- (void)addValidator:(id<HyValidator>)validator;

// Validation
- (void)validate;

@end

UITextField+Validation.m

@interface UITextField (Validation_Private)

@property (nonatomic, strong) NSMutableArray * validators;
@property (nonatomic) HyValidationState validationState;

@end

@implementation UITextField (Validation_Private)

- (NSMutableArray*)validators
{
    if (self.validators == nil) {
        self.validators = [[NSMutableArray alloc] init];
    }
    return self.validators;
}

- (void)setValidators:(NSMutableArray *)validators
{
    self.validators = validators;
}

- (HyValidationState)validationState
{

}

- (void)setValidationState:(HyValidationState)validationState
{

}

- (void)addValidator:(id<HyValidator>)validator
{
    [[self validators] addObject:validator];
}

- (void)validate
{

}

@end

The question is: how do I initialise validators and validationState?

Upvotes: 1

Views: 280

Answers (2)

bbum
bbum

Reputation: 162712

Don't use categories for this. Subclass instead. Or, better yet, use the UITextField's delegate to do the validation, as intended.

Using categories to extend the behavior of existing system classes is generally considered to be bad design.

By using delegation, you can decouple input validation from a specific input class and, thus, your validation can be easily re-used across other input mechanisms.

Upvotes: 4

nprd
nprd

Reputation: 1942

You want to add a storage to your class UITextField (simple ivar to hold the data). Since you don't have the code you can't extend the class. However in objective C you can achieve this using associated reference. ObjC Runtime comes handy helping you to attach a storage to your class and make you interact with the storage as if it was built in within the class.

An example of how to achieve this is found in Ole Begemann blog here http://oleb.net/blog/2011/05/faking-ivars-in-objc-categories-with-associative-references/

Upvotes: 2

Related Questions