1.映射绑定做了缓存
YYModel有两个映射方法:modelCustomPropertyMapper和modelContainerPropertyGenericClass,当时使用的时候发现这两个方法只调用一次,一开始以为是使用load方法调用的,看了代码才发现不是的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
+ (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对象:
1 2 3 4 |
+ (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:
1 2 3 |
- (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,这部分篇幅限制就不多做介绍了
开源库的存在大大方便了我们的开发,我们在使用的同时应该多去阅读源码,每个人写代码的习惯都不一样,不对比怎么能知道自己习惯的好坏呢,而且最重要的是可以学习到优秀的代码逻辑,什么时候用什么,该怎么用,为什么这样用。大神不是一开始就是大神,都是一步一步走出来,不学习怎么能成长。