浏览代码

draft support for custom model class

Yuri Buyanov 9 年之前
父节点
当前提交
1413d3d6c4
共有 2 个文件被更改,包括 40 次插入5 次删除
  1. 5 0
      YYModel/NSObject+YYModel.h
  2. 35 5
      YYModel/NSObject+YYModel.m

+ 5 - 0
YYModel/NSObject+YYModel.h

@@ -319,6 +319,11 @@
  */
 + (NSDictionary *)modelContainerPropertyGenericClass;
 
+/**
+ TODO: description and example
+ */
++ (Class)modelCustomClassForDictionary:(NSDictionary*)dictionary;
+
 /**
  All the properties in blacklist will be ignored in model transform process.
  Returns nil to ignore this feature.

+ 35 - 5
YYModel/NSObject+YYModel.m

@@ -344,6 +344,7 @@ static force_inline id YYValueForKeyPath(__unsafe_unretained NSDictionary *dic,
     
     BOOL _hasCustomTransformFromDictionary;
     BOOL _hasCustomTransformToDictionary;
+    BOOL _hasCustomClassFromDictionary;
 }
 @end
 
@@ -452,6 +453,7 @@ static force_inline id YYValueForKeyPath(__unsafe_unretained NSDictionary *dic,
     _nsType = YYClassGetNSType(cls);
     _hasCustomTransformFromDictionary = ([cls instancesRespondToSelector:@selector(modelCustomTransformFromDictionary:)]);
     _hasCustomTransformToDictionary = ([cls instancesRespondToSelector:@selector(modelCustomTransformToDictionary:)]);
+    _hasCustomClassFromDictionary = ([cls respondsToSelector:@selector(modelCustomClassForDictionary:)]);
     
     return self;
 }
@@ -731,7 +733,13 @@ static void ModelSetValueForProperty(__unsafe_unretained id model,
                                 if ([one isKindOfClass:meta->_genericCls]) {
                                     [objectArr addObject:one];
                                 } else if ([one isKindOfClass:[NSDictionary class]]) {
-                                    NSObject *newOne = [meta->_genericCls new];
+                                    _YYModelMeta *modelMeta = [_YYModelMeta metaWithClass:meta->_genericCls];
+                                    Class clazz = meta->_genericCls;
+                                    if (modelMeta->_hasCustomClassFromDictionary) {
+                                        clazz = [clazz modelCustomClassForDictionary:one] ?: clazz;
+                                    }
+                                    
+                                    NSObject *newOne = [clazz new];
                                     [newOne yy_modelSetWithDictionary:one];
                                     if (newOne) [objectArr addObject:newOne];
                                 }
@@ -770,7 +778,13 @@ static void ModelSetValueForProperty(__unsafe_unretained id model,
                             NSMutableDictionary *dic = [NSMutableDictionary new];
                             [((NSDictionary *)value) enumerateKeysAndObjectsUsingBlock:^(NSString *oneKey, NSObject *oneValue, BOOL *stop) {
                                 if ([oneValue isKindOfClass:[NSDictionary class]]) {
-                                    NSObject *o = [meta->_genericCls new];
+                                    _YYModelMeta *modelMeta = [_YYModelMeta metaWithClass:meta->_genericCls];
+                                    Class clazz = meta->_genericCls;
+                                    if (modelMeta->_hasCustomClassFromDictionary) {
+                                        clazz = [clazz modelCustomClassForDictionary:oneValue] ?: clazz;
+                                    }
+
+                                    NSObject *o = [clazz new];
                                     [o yy_modelSetWithDictionary:(id)oneValue];
                                     if (o) dic[oneKey] = o;
                                 }
@@ -802,7 +816,12 @@ static void ModelSetValueForProperty(__unsafe_unretained id model,
                             if ([one isKindOfClass:meta->_genericCls]) {
                                 [set addObject:one];
                             } else if ([one isKindOfClass:[NSDictionary class]]) {
-                                NSObject *newOne = [meta->_genericCls new];
+                                _YYModelMeta *modelMeta = [_YYModelMeta metaWithClass:meta->_genericCls];
+                                Class clazz = meta->_genericCls;
+                                if (modelMeta->_hasCustomClassFromDictionary) {
+                                    clazz = [clazz modelCustomClassForDictionary:one] ?: clazz;
+                                }
+                                NSObject *newOne = [clazz new];
                                 [newOne yy_modelSetWithDictionary:one];
                                 if (newOne) [set addObject:newOne];
                             }
@@ -840,7 +859,12 @@ static void ModelSetValueForProperty(__unsafe_unretained id model,
                     if (one) {
                         [one yy_modelSetWithDictionary:value];
                     } else {
-                        one = [meta->_cls new];
+                        _YYModelMeta *modelMeta = [_YYModelMeta metaWithClass:meta->_cls];
+                        Class clazz = meta->_cls;
+                        if (modelMeta->_hasCustomClassFromDictionary) {
+                            clazz = [clazz modelCustomClassForDictionary:value] ?: clazz;
+                        }
+                        one = [clazz new];
                         [one yy_modelSetWithDictionary:value];
                         ((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, (id)one);
                     }
@@ -1092,7 +1116,13 @@ static id ModelToJSONObjectRecursive(NSObject *model) {
 + (instancetype)yy_modelWithDictionary:(NSDictionary *)dictionary {
     if (!dictionary || dictionary == (id)kCFNull) return nil;
     if (![dictionary isKindOfClass:[NSDictionary class]]) return nil;
-    NSObject *one = [self new];
+    _YYModelMeta *modelMeta = [_YYModelMeta metaWithClass:[self class]];
+    Class clazz = [self class];
+    if (modelMeta->_hasCustomClassFromDictionary) {
+        clazz = [clazz modelCustomClassForDictionary:dictionary] ?: clazz;
+    }
+
+    NSObject *one = [clazz new];
     [one yy_modelSetWithDictionary:dictionary];
     return one;
 }