YYModel代码分析笔记

1.映射绑定做了缓存

YYModel有两个映射方法:modelCustomPropertyMapper和modelContainerPropertyGenericClass,当时使用的时候发现这两个方法只调用一次,一开始以为是使用load方法调用的,看了代码才发现不是的。

YYModel代码分析笔记_第1张图片
yymodel方法流程图.png

从上图的线程调用可以看出来,modelContainerPropertyGenericClass是在第一次调用yy_modelSetWithJSON的时候调用的,我们把代码定位到下面的代码

+ (instancetype)metaWithClass:(Class)cls {
    if (!cls) return nil;
    static CFMutableDictionaryRef cache;
    static dispatch_once_t onceToken;
    static dispatch_semaphore_t lock;
    dispatch_once(&onceToken, ^{
        cache = CFDictionaryCreateMutable(CFAllocatorGetDefault(), 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
        lock = dispatch_semaphore_create(1);
    });
    dispatch_semaphore_wait(lock, DISPATCH_TIME_FOREVER);
    _YYModelMeta *meta = CFDictionaryGetValue(cache, (__bridge const void *)(cls));
    dispatch_semaphore_signal(lock);
    if (!meta || meta->_classInfo.needUpdate) {
        meta = [[_YYModelMeta alloc] initWithClass:cls];
        if (meta) {
            dispatch_semaphore_wait(lock, DISPATCH_TIME_FOREVER);
            CFDictionarySetValue(cache, (__bridge const void *)(cls), (__bridge const void *)(meta));
            dispatch_semaphore_signal(lock);
        }
    }
    return meta;
}

分析:
meta = [[_YYModelMeta alloc] initWithClass:cls];会调用映射绑定,而不是我之前猜测的在load或initialize方法里面调用的。
使用CFDictionary创建了cache缓存,dispatch_once(&onceToken, ^{})确保了初始化过程只有一次。
线程安全方面使用的是dispatch_semaphore ,之前我做过实验,dispatch_semaphore 的性能还是很高的,速度在我的测试中排列第三,比他高的还有一个递归锁,还有一个dispatch_barrier_async/dispatch_barrier_sync,然而递归锁在这里不太合适,dispatch_barrier的话需要进行线程切换,所以被作者放弃了。
meta的创建没有在线程锁里面,虽然这样meta可能会被创建多次,这里这样做主要是保证了锁的区域足够小。

2.json到model,model到NSDictionary或者NSArray的转换

根据映射可以直接转换到model对象:

+ (nullable instancetype)yy_modelWithJSON:(id)json;
+ (nullable instancetype)yy_modelWithDictionary:(NSDictionary *)dictionary;
- (BOOL)yy_modelSetWithJSON:(id)json;
- (BOOL)yy_modelSetWithDictionary:(NSDictionary *)dic;

根据映射可以转成NSDictionary或者NSArray或者NSData或者NSString:

- (nullable id)yy_modelToJSONObject;
- (nullable NSData *)yy_modelToJSONData;
- (nullable NSString *)yy_modelToJSONString;

这里需要注意
yy_modelToJSONObject方法并不是model一定会转成[String:String]或者[String]类型的,而是[String:AnyObject]或者[AnyObject],也就是说,model转出来的可能字典嵌套数组的类型,如果说需要把数组转成json字符串传给服务器,那么还是需要进行二次转换的。

3.yy_modelCopy

yy_modelCopy现在有BUG,model是生成一个新的对象了,但是model里面的属性并没有,体现在 NSMutablexxxx和其他自定义类上,由于内存地址还是一个,对这些属性的修改会造成原model的修改

4.runtime

YYModel大量的使用了runtime,属性的获取,赋值等操作都使用了runtime,这部分篇幅限制就不多做介绍了

开源库的存在大大方便了我们的开发,我们在使用的同时应该多去阅读源码,每个人写代码的习惯都不一样,不对比怎么能知道自己习惯的好坏呢,而且最重要的是可以学习到优秀的代码逻辑,什么时候用什么,该怎么用,为什么这样用。大神不是一开始就是大神,都是一步一步走出来,不学习怎么能成长。

你可能感兴趣的:(YYModel代码分析笔记)