Custom setter with error out parameter#564
Conversation
|
Ah excellent! :) I have been wanting this for a while - much cleaner than the previous solution. Will review and probably make a couple of tweaks. |
billinghamj
left a comment
There was a problem hiding this comment.
Okay, have reviewed in detail. Most of the changes are stylistic to fit in with the newer code in the project (I know much of the older code is quite different).
Finally, please add tests for both the old and new use of the setters (with BOOL and void return types), add something to show that the old method is deprecated, and update the readme please
| if ([self __customSetValue:jsonValue forProperty:property]) { | ||
| NSError* customSetErr = nil; | ||
| if ([self __customSetValue:jsonValue forProperty:property error:&customSetErr]) { | ||
| if((err != nil) && (customSetErr != nil)) |
There was a problem hiding this comment.
Please update to:
if (err != nil && customSetErr != nil)
*err = customSetErr;| // check for custom setter, than the model doesn't need to do any guessing | ||
| // how to read the property's value from JSON | ||
| if ([self __customSetValue:jsonValue forProperty:property]) { | ||
| NSError* customSetErr = nil; |
There was a problem hiding this comment.
Please change to NSError *customSetErr
There was a problem hiding this comment.
Do you use any formatter tool to take care of formatting. Something like uncrustify?
There was a problem hiding this comment.
Unfortunately not at present, no
| -(void)__addCustomSetterForName:(NSString*) name | ||
| withSuffix:(NSString*) suffix | ||
| key:(NSString*) key | ||
| toProperty:(JSONModelClassProperty*) p{ |
There was a problem hiding this comment.
Please change to something more like:
- (void)__addCustomSetterToProperty:(JSONModelClassProperty *)property withValueType:(NSString *)valueType
{- all args/params on a single line
- curly brace on a new line
- space before pointer asterisks, rather than after
- no space before variable names
- more clear variable/param naming
- avoiding unneeded params
| p.customSetters[key] = [[JSONModelCustomSetter alloc] initWithValue:setterValue withErrorOutParam:NO]; | ||
| } | ||
|
|
||
| SEL setterWithError = NSSelectorFromString([NSString stringWithFormat:@"set%@With%@:error:", name, suffix]); |
There was a problem hiding this comment.
Check for the error setter first, then return within the respondsToSelector conditional block
|
|
||
| #pragma mark - custom transformations | ||
| - (BOOL)__customSetValue:(id <NSObject>)value forProperty:(JSONModelClassProperty *)property | ||
| - (BOOL)__customSetValue:(id <NSObject>)value forProperty:(JSONModelClassProperty *)property error:(NSError**) error |
There was a problem hiding this comment.
Space before pointer asterisks
|
|
||
| if ([self respondsToSelector:setterWithError]){ | ||
| NSValue* setterValue = [NSValue valueWithBytes:&setterWithError objCType:@encode(SEL)]; | ||
| p.customSetters[key] = [[JSONModelCustomSetter alloc] initWithValue:setterValue withErrorOutParam:YES]; |
There was a problem hiding this comment.
Init with SEL object directly, not the NSValue
There was a problem hiding this comment.
(NSValue was only used because an NSDictionary cannot hold a value type - e.g. SEL, thus there is no need to use NSValue at all)
| return NO; | ||
|
|
||
| SEL setter = nil; | ||
| [customSetter.value getValue:&setter]; |
There was a problem hiding this comment.
Pull SEL directly from JSONModelCustomSetter property, rather than using an NSValue
|
|
||
| @interface JSONModelCustomSetter : NSObject | ||
|
|
||
| @property ( nonatomic, readonly, strong) NSValue* value; |
| @property ( nonatomic, readonly, strong) NSValue* value; | ||
| @property ( nonatomic, readonly, assign) BOOL withErrorOutParam; | ||
|
|
||
| - (instancetype)initWithValue:(NSValue*)value withErrorOutParam:(BOOL) withErrorOutParam; |
There was a problem hiding this comment.
Change to:
- (instancetype)initWithSelector:(SEL)selector;Determine the presence of the error param based on the selector - don't pass this in
| if (p.customSetters[key]) | ||
| return; | ||
|
|
||
| SEL setter = NSSelectorFromString([NSString stringWithFormat:@"set%@With%@:", name, suffix]); |
There was a problem hiding this comment.
Please move all this logic into JSONModelCustomSetter - probably something like:
JSONModelCustomSetter *setter = [JSONModelCustomSetter setterForObj:self propertyName:name valueType:suffix];
if (setter)
p.customSetters[key] = setter;There was a problem hiding this comment.
From my point of view, anyway, I should first check, does the selector exist, and only then create JSONModelCustomSetter. So I can only hide into the class the magic of wrapping into the NSValue ( which anyway will be removed)
There was a problem hiding this comment.
If the selector doesn't exist, setterForObj would return nil.
|
Also needs to be rebased |
524b0cb to
13ea1b6
Compare
|
Do you think old method should be deprecated? I would leave both of them, as in many cases there is no need for error processing in custom setter. |
|
Please check new update |
|
Yes the old method should be deprecated - we avoid supporting more than one way of doing a given thing at once generally, as it keeps it more maintainable. |
|
Added the warning about deprecation of the old method |
Implemented custom possibility to use custom setter with error out parameter
It allows to use another JSONModel initializers inside custom setter and propagate error to the topmost. Like here: