Using the following models as examples, what are the best practices of handling polymorphism within JSONModel?@interface GameModel : JSONModel@property (nonatomic, assign) long id;@property (nonatomic, assign) NSArray<GameEventModel> *events;/* ...*/@end@interface GameEventModel : JSONModel@property (nonatomic, assign) long long timestamp;/* ...*/@end@interface GameTouchEventModel : GameEventModel@property (nonatomic, assign) CGPoint point;/* ...*/@end使用JSON字符串{id:1, events:[{point:{x:1, y:1}, timestamp:...}]} JSONModel将使用GameEventModel并忽略point属性.JSONModel will use the GameEventModel and ignore the point property.最好使用包含type属性和info属性的通用GameEventModel,例如... Would it be better to use a generic GameEventModel which contains a type property and info property such as...@interface GameTouchEventModel : GameEventModel@property (nonatomic, strong) NSString *type;@property (nonatomic, strong) NSDictionary *info;@end因此模型可以接受JSON作为{id:1, events:[{ type:"GameTouchEventModel", info:{ point:{x:1, y:1}, timestamp:... } }]} And therefore the model could accept JSON as {id:1, events:[{ type:"GameTouchEventModel", info:{ point:{x:1, y:1}, timestamp:... } }]}这种方法的问题是更难阅读代码,并且没有其他编译器警告/错误.The problem with this approach is harder to read code and no compiler warnings/errors amongst others.没有办法在JSONModel中使用多态模型吗?Is there no way to use polymorphic models in JSONModel?推荐答案我们通过对JSONModel.m的2个小改动解决了此问题,引入了一个新的特殊JSON属性__subclass,该属性由JSONModel解析器获取并使用该值作为对象类型.必须将__subclass作为保留关键字(因此,任何模型都不能使用__subclass作为属性名称).We solved this with 2 minor alterations to JSONModel.m, introducing a new special JSON property __subclass which is picked up by the JSONModel parser and uses the value as the object type. __subclass is required to be a reserved keyword (therefore no models can use __subclass as a property name).对JSONModel.m // ...-(id)initWithDictionary:(NSDictionary*)dict error:(NSError**)err{ // ... if ([self __isJSONModelSubClass:property.type]) { //initialize the property's model, store it JSONModelError* initErr = nil; -- id value = [[property.type alloc] initWithDictionary: jsonValue error:&initErr]; ++ id value; ++ if([jsonValue valueForKey:@"subclass"] != NULL) ++ { ++ Class jsonSubclass = NSClassFromString([d valueForKey:@"subclass"]); ++ if(jsonSubclass) ++ obj = [[jsonSubclass alloc] initWithDictionary:d error:&initErr]; ++ } ++ else ++ value = [[property.type alloc] initWithDictionary: jsonValue error:&initErr]; //...//...+(NSMutableArray*)arrayOfModelsFromDictionaries:(NSArray*)array error:(NSError**)err{ // ... for (NSDictionary* d in array) { JSONModelError* initErr = nil; -- id obj = [[self alloc] initWithDictionary:d error:&initErr]; ++ id obj; ++ if([d valueForKey:@"subclass"] != NULL) ++ { ++ Class jsonSubclass = NSClassFromString([d valueForKey:@"subclass"]); ++ if(jsonSubclass) ++ obj = [[jsonSubclass alloc] initWithDictionary:d error:&initErr]; ++ } ++ else ++ obj = [[self alloc] initWithDictionary:d error:&initErr]; // ... // ...注意:如果_subclass ed的JSON模型类不存在,则模型将回退到超类.NOTE: If the _subclass'ed JSON model class doesn't exist, then the model will fallback to the superclass.这将适用于以下模型@interface GameModel : JSONModel@property (nonatomic, assign) long id;@property (nonatomic, assign) NSArray<GameEventModel> *events;@end@protocol GameEventModel@end@interface GameEventModel : JSONModel@property (nonatomic, assign) long long timestamp;@end@interface GameTouchEventModel : GameEventModel@property (nonatomic, strong) NSArray *point;@end传递JSON字符串{id:1, events:[ { __subclass:'GameTouchEventModel', timestamp:1, point: [0,0] } ] } 这篇关于JSONModel iOS和多态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!
10-21 10:05