New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Custom setter with error out parameter #564
base: master
Are you sure you want to change the base?
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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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
JSONModel/JSONModel/JSONModel.m
Outdated
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please update to:
if (err != nil && customSetErr != nil)
*err = customSetErr;
JSONModel/JSONModel/JSONModel.m
Outdated
@@ -327,7 +328,12 @@ -(BOOL)__importDictionary:(NSDictionary*)dict withKeyMapper:(JSONKeyMapper*)keyM | |||
|
|||
// 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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please change to NSError *customSetErr
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you use any formatter tool to take care of formatting. Something like uncrustify?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately not at present, no
JSONModel/JSONModel/JSONModel.m
Outdated
-(void)__addCustomSetterForName:(NSString*) name | ||
withSuffix:(NSString*) suffix | ||
key:(NSString*) key | ||
toProperty:(JSONModelClassProperty*) p{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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
JSONModel/JSONModel/JSONModel.m
Outdated
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Check for the error setter first, then return within the respondsToSelector
conditional block
JSONModel/JSONModel/JSONModel.m
Outdated
@@ -841,22 +861,30 @@ -(id)__reverseTransform:(id)value forProperty:(JSONModelClassProperty*)property | |||
} | |||
|
|||
#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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Space before pointer asterisks
JSONModel/JSONModel/JSONModel.m
Outdated
|
||
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Init with SEL
object directly, not the NSValue
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(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)
JSONModel/JSONModel/JSONModel.m
Outdated
return NO; | ||
|
||
SEL setter = nil; | ||
[customSetter.value getValue:&setter]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull SEL
directly from JSONModelCustomSetter property, rather than using an NSValue
|
||
@interface JSONModelCustomSetter : NSObject | ||
|
||
@property ( nonatomic, readonly, strong) NSValue* value; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change to SEL
type
@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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change to:
- (instancetype)initWithSelector:(SEL)selector;
Determine the presence of the error param based on the selector - don't pass this in
JSONModel/JSONModel/JSONModel.m
Outdated
if (p.customSetters[key]) | ||
return; | ||
|
||
SEL setter = NSSelectorFromString([NSString stringWithFormat:@"set%@With%@:", name, suffix]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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: