本文承接上文,解码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));

Core Foundation对象

在上面使用缓存的期间,均使用了CoreFoundation对象以及对应的方法。

遍历与查找

//黑白名单超找对象时,先将黑白名单转换为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));