本文承接上文,解码YYModel(一)基础。
在上文最后,列出一个实例:
@interface YYMessage : NSObject
@property (nonatomic, assign) uint64_t messageId;
@property (nonatomic, strong) NSString *content;
@property (nonatomic, strong) NSDate *time;
@property (nonatomic ,copy) NSString *name;
@end
@implementation YYMessage
+ (nullable NSArray<NSString *> *)modelPropertyBlacklist
{
return @[@"name"];
}
+ (NSDictionary *)modelCustomPropertyMapper {
return @{@"messageId":@[@"id", @"ID", @"mes_id"],
@"time":@"t",
@"name":@"user.name"
};
}
- (BOOL)modelCustomTransformFromDictionary:(NSDictionary *)dic {
uint64_t timestamp = [dic unsignedLongLongValueForKey:@"t" default:0];
self.time = [NSDate dateWithTimeIntervalSince1970:timestamp / 1000.0];
return YES;
}
- (void)modelCustomTransformToDictionary:(NSMutableDictionary *)dic {
dic[@"t"] = @([self.time timeIntervalSince1970] * 1000).description;
}
基于YYModel作者,在博文中提出的tips,理顺了下面几点性能优化的点:
在下面方法中
+ (instancetype)modelWithDictionary:(NSDictionary *)dictionary {
if (!dictionary || dictionary == (id)kCFNull) return nil;
if (![dictionary isKindOfClass:[NSDictionary class]]) return nil;
Class cls = [self class];
_YYModelMeta *modelMeta = [_YYModelMeta metaWithClass:cls]; //构建缓存
if (modelMeta->_hasCustomClassFromDictionary) {
cls = [cls modelCustomClassForDictionary:dictionary] ?: cls;
}
NSObject *one = [cls new];
if ([one modelSetWithDictionary:dictionary]) return one; //使用缓存
return nil;
}
_YYModelMeta *meta = CFDictionaryGetValue(cache, (__bridge const void *)(cls));
YYClassInfo *info = CFDictionaryGetValue(class_isMetaClass(cls) ? metaCache : classCache, (__bridge const void *)(cls));
在上面使用缓存的期间,均使用了CoreFoundation对象以及对应的方法。
NSSet
,而不是NSArray
。因为NSSet
通过遍历查找,而NSArray
则是遍历查找。//黑白名单超找对象时,先将黑白名单转换为NSSet
blacklist = [NSSet setWithArray:properties];
whitelist = [NSSet setWithArray:properties];
//switch/case而不是if/else
//switch/case在库里,到处都是。
//NSDictionary
//在使用缓存的时候,获取对应对象的meta时,根据NSDictionary来实现
_YYModelMeta *meta = CFDictionaryGetValue(cache, (__bridge const void *)(cls));