YYModel 源码解读之NSObject+YYModel.h

Posted 马在路上

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了YYModel 源码解读之NSObject+YYModel.h相关的知识,希望对你有一定的参考价值。

接下来我们继续向下看

typedef struct {
    void *modelMeta;  ///< _YYModelMeta
    void *model;      ///< id (self)
    void *dictionary; ///< NSDictionary (json)
} ModelSetContext;

这是一个c的结构体,在c中 void * 相当于 oc 中的 id 类型

那么 为什么使用c的结构体呢,最主要的使用场景就是我们需要同时使用多个参数的情况下,可以使用c的结构体

/**
 Apply function for dictionary, to set the key-value pair to model.
 
 @param _key     should not be nil, NSString.
 @param _value   should not be nil.
 @param _context _context.modelMeta and _context.model should not be nil.
 */
static void ModelSetWithDictionaryFunction(const void *_key, const void *_value, void *_context) {
    ModelSetContext *context = _context;
    __unsafe_unretained _YYModelMeta *meta = (__bridge _YYModelMeta *)(context->modelMeta);
    __unsafe_unretained _YYModelPropertyMeta *propertyMeta = [meta->_mapper objectForKey:(__bridge id)(_key)];
    __unsafe_unretained id model = (__bridge id)(context->model);
    while (propertyMeta) {
        if (propertyMeta->_setter) {
            ModelSetValueForProperty(model, (__bridge __unsafe_unretained id)_value, propertyMeta);
        }
        propertyMeta = propertyMeta->_next;
    };
}

上边的代码的主要作用是 根据 一个 id 类型的_value 一个 id 类型的_key 和_context 结构体信息,社会value 到相应的属性中

 

/**
 Apply function for model property meta, to set dictionary to model.
 
 @param _propertyMeta should not be nil, _YYModelPropertyMeta.
 @param _context      _context.model and _context.dictionary should not be nil.
 */
static void ModelSetWithPropertyMetaArrayFunction(const void *_propertyMeta, void *_context) {
    ModelSetContext *context = _context;
    
    // 这个dictionary 是 json 字典
    __unsafe_unretained NSDictionary *dictionary = (__bridge NSDictionary *)(context->dictionary);
    __unsafe_unretained _YYModelPropertyMeta *propertyMeta = (__bridge _YYModelPropertyMeta *)(_propertyMeta);
    if (!propertyMeta->_setter) return;
    id value = nil;
    
    // 如果property 映射了 多个jsonkey
    if (propertyMeta->_mappedToKeyArray) {
        // 这个是之前的函数,目的是根据字典和映射的jsonkey 取出对应的值,当获取到第一个不为空的值的情况下,停止遍历
        value = YYValueForMultiKeys(dictionary, propertyMeta->_mappedToKeyArray);
        
        
    } else if (propertyMeta->_mappedToKeyPath) {
        
        value = YYValueForKeyPath(dictionary, propertyMeta->_mappedToKeyPath);
    } else {
        value = [dictionary objectForKey:propertyMeta->_mappedToKey];
    }
    
    if (value) {
        __unsafe_unretained id model = (__bridge id)(context->model);
        ModelSetValueForProperty(model, value, propertyMeta);
    }
}

上边的代码也是一个赋值的函数,在一种propertyMeta 和context 的参数的情况下 ,实现的赋值方法

 

接下来的这个方法主要是mode to json  模型转字典的核心方法,目的是对model 进行预处理

注意,该方法只是对一个NSObject对象做预处理,并没有转JSON对象

苹果 规定使用 NSJSONSerialization 转换成JSONObject的要求:

NSArray 对象
数组元素只能是 NSString、NSNumber、NSNull
NSDictionary 对象
key 必须是 NSString
value只能是 NSString、NSNumber、NSNull
该函数对传入的NSObject对象为如下所有类型时做的预处理:

NSData >>> 不能转换成JSON

NSString >>> NSString

NSNumber >>> NSNumber
NSURL >>> NSString
NSAttributedString >>> NSString
NSDate >>> 使用DateFormat转换成NSString

NSArray

先判断NSArray是否可以被JSON化
如果可以,直接返回NSArray
如果不可以
创建一个新的NSArray
遍历之前NSArray中的每一个元素
递归将当前元素解析成 NSString、NSNumber
将解析后的元素添加到数组
返回新的数组
NSSet
NSSet >>> NSArray
走NSArray的流程
NSDictionary
类似NSArray
自定义NSObject类,非Foundation类
将当前实体类对象 >>> 使用NSDictionary对象来重新组装
属性值 >>> NSDictionary字典key-value
最终 实体类对象 >>> NSDictionary对象

 

以上是关于YYModel 源码解读之NSObject+YYModel.h的主要内容,如果未能解决你的问题,请参考以下文章

YYModel 源码解读之NSObject+YYModel.h

YYModel 源码解读之YYModel.h

YYModel 源码解读之YYClassInfo.h

YYModel 源码解读之YYClassInfo.h

YYModel 源码解读之YYClassInfo.h

iOS YYModel使用详解