I'd strongly advise the OP it's better for them to create a custom class for 
their model objects, rather than go down this route of globally modifying 
NSMutableDictionary's API.

On 13 Dec 2012, at 22:18, jonat...@mugginsoft.com wrote:

> On 13 Dec 2012, at 11:54, jonat...@mugginsoft.com wrote:
> 
>> I bind an NSArray of NSMutableDictionary instances to an NSTableView and 
>> enable NSTableColumn editing..
>> 
>> How can I best implement KVO based validation when editing the view?
>> 
>> Subclassing NSArray controller is a no go as validateValue:forKeyPath:error 
>> is never called.
>> Subclassing the NSMutableDictionary model obviously isn't desirable.
>> 
>> I can refactor the NSMutableDictionary instances into custom objects and use 
>> model based validation if needed.
>> 
>> However, binding dictionaries into table views is often convenient so a 
>> working validation strategy would be useful.
>> 
>> Jonathan
> 
> The following category enables NSMutableDictionary KVC validation routing to 
> a delegate.
> 
> NSMutableDictionary *connection = [self selectedConnection];
> connection.validationDelegate = self;
> 
> The delegate then performs validation in:
> 
> - (BOOL)validateValue:(id *)ioValue forKey:(NSString *)key error:(NSError 
> **)outError sender:(NSMutableDictionary *)sender
> 
> See https://github.com/mugginsoft/NSMutableDictionary-KVCValidation
> 
> Simple refactoring would enable routing of KVC validation for any class.
> 
> Jonathan
> 
> 
> #import "NSMutableDictionary+KVCValidation.h"
> #import <objc/runtime.h>
> 
> const char validationDelegateKey;
> 
> /*
> 
> MethodSwizzle()
> 
> ref: 
> http://www.mikeash.com/pyblog/friday-qa-2010-01-29-method-replacement-for-fun-and-profit.html
> 
> */
> void MethodSwizzle(Class klass, SEL origSEL, SEL overrideSEL)
> {
>    Method origMethod = class_getInstanceMethod(klass, origSEL);
>    Method overrideMethod = class_getInstanceMethod(klass, overrideSEL);
> 
>    // try and add instance method with original selector that points to new 
> implementation
>    if (class_addMethod(klass, origSEL, 
> method_getImplementation(overrideMethod), 
> method_getTypeEncoding(overrideMethod))) {
> 
>        // add or replace method so that new selector points to original 
> method 
>        class_replaceMethod(klass, overrideSEL, 
> method_getImplementation(origMethod), method_getTypeEncoding(origMethod));
>    } else {
> 
>        // class already has an override method so just swap the 
> implementations.
>        method_exchangeImplementations(origMethod, overrideMethod);
>    }
> }
> 
> @implementation NSMutableDictionary (KVCValidation)
> 
> /*
> 
> + load
> 
> */
> + (void)load
> {
>    MethodSwizzle(self, @selector(validateValue:forKey:error:), 
> @selector(swizzle_validateValue:forKey:error:));
> }
> 
> /*
> 
> - setValidationDelegate:
> 
> */
> - (void)setValidationDelegate:(id)validationDelegate
> {
>    objc_setAssociatedObject(self, &validationDelegateKey, validationDelegate, 
> OBJC_ASSOCIATION_RETAIN);
> }
> 
> /*
> 
> - validationDelegate
> 
> */
> - (id)validationDelegate
> {
>    return objc_getAssociatedObject(self, &validationDelegateKey);
> }
> 
> /*
> 
> - swizzle_validateValue:forKey:error:
> 
> */
> - (BOOL)swizzle_validateValue:(id *)ioValue forKey:(NSString *)key 
> error:(NSError **)outError
> {
>    id validationDelegate = self.validationDelegate;
>    SEL validationSelector = @selector(validateValue:forKey:error:sender:);
>    BOOL isValid = NO;
> 
>    if ([validationDelegate respondsToSelector:validationSelector]) {
>        isValid = [validationDelegate validateValue:ioValue forKey:key 
> error:outError sender:self];
>    } else {
>        // remember, we swap IMPS at run time
>        isValid = [self swizzle_validateValue:ioValue forKey:key 
> error:outError];
>    }
> 
>    return isValid;
> }
> @end
> 
> Jonathan
> 
> 
> _______________________________________________
> 
> Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)
> 
> Please do not post admin requests or moderator comments to the list.
> Contact the moderators at cocoa-dev-admins(at)lists.apple.com
> 
> Help/Unsubscribe/Update your Subscription:
> https://lists.apple.com/mailman/options/cocoa-dev/cocoadev%40mikeabdullah.net
> 
> This email sent to cocoa...@mikeabdullah.net


_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to