PBpb

ios 中(data) protocol buffer, Jso

2018-12-11  本文已影响0人  jianshudxw

前言

前些天,程序出现了一个bug:数据莫名的丢失。由于业务复杂,折腾了好久才解决,在网上也没有找的答案, 故,记下来。

现象

  1. 将 protobuf 的 Data 转换为 Json
  2. Json 转为 Model
  3. 发现 Model 的有些字段数据丢失
  4. 发现是有 Has* 对应的 字段变为nil了
  5. 这个问题发生在32位真机上。

知识点

例如

Message *msg = (一个有数据的msg)
content 是嵌套的Message
NSLog(@"msg.content = ",msg.content)
//有数据
msg.hasContent = YES;
NSLog(@"msg.content = ",msg.content)
//打印msg.content =nil

修改方案

本着不修改第三方库的原则,项目中使用了 YYModel。添加了个分类 GPBMessage (YYModel) 在 Json 转Model 时过滤掉has_count 先这样解决了问题。

- (NSString *)uppercaseFirstCharacter:(NSString*)str {
    NSRange range = NSMakeRange(0,1);
    NSString *upperFirstCharacter = [[str substringToIndex:1] uppercaseString];
    return [str stringByReplacingCharactersInRange:range withString:upperFirstCharacter];
}

- (NSDictionary *)modelCustomWillTransformFromDictionary:(NSDictionary *)dic {
    NSMutableDictionary *filteredDic = [[NSMutableDictionary alloc] initWithDictionary:dic];
    GPBDescriptor *descriptor = [self descriptor];
    for (GPBFieldDescriptor *fd in descriptor.fields) {
        Ivar ivar = class_getInstanceVariable([fd class], "hasOrCountSel_");
        //         当使用ARC后请使用  BOOL ok = NO; ok = object_getIvar(fd, ivar);
        //         https://stackoverflow.com/questions/8356232/object-getivar-fails-to-read-the-value-of-bool-ivar
        unsigned char val;
        val = ((unsigned char (*)(id, Ivar))object_getIvar)(fd, ivar);
        //         RCTrace(@"Looks like I got: %u (or character %c) %@", val, val,fd.name);
        if (val != 0 ) {
            NSString *countKey = [NSString stringWithFormat:@"%@_Count",fd.name];
            [filteredDic removeObjectForKey:countKey];
            NSString *hasKey = [NSString stringWithFormat:@"has%@",[self uppercaseFirstCharacter:fd.name]];
            [filteredDic removeObjectForKey:hasKey];
        }
    }
    return filteredDic;
}
上一篇 下一篇

猜你喜欢

热点阅读