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