「iOS」——YYModel学习

iOS学习

前言

YYModel是YYKit的高效组件之一,在实际场景中的非常实用,在项目中使用MVC架构时,可以简化数据处理。在性能上相比JSONMode更加高效。在此对使用做简单学习。


优势

原作者给出如下YYModel的优势:

  • 高性能:转换效率接近手写代码。
  • 自动类型转换:对象类型能自动转换。
  • 类型安全:在转换过程中所有的类型都会被验证,以确保类型安全。
  • 非侵入性:不需要让模型类继承自基类。
  • 轻量级:整个库只包含5个文件。
  • 文档和测试覆盖:100%文档覆盖,99.6代码覆盖。

使用方法

简单的Model与JSON互转

这里需要注意:

当 JSON/Dictionary 中的对象类型与 Model 属性不一致时,YYModel 将会进行如下自动转换。自动转换不支持的值将会被忽略,以避免各种潜在的崩溃问题。

JSON/Dictionary Model
NSString NSNumber,NSURL,SEL,Class
NSNumber NSString
NSString/NSNumber 基础类型 (BOOL,int,float,NSUInteger,UInt64,...) NaN 和 Inf 会被忽略
NSString NSDate 以下列格式解析: yyy-MM-dd yyyy-MM-dd HH:mm:ss yyyy-MM-dd'T'HH:mm:ss yyyy-MM-dd'T'HH:mm:ssZ EEE MMM dd HH:mm:ss Z yyyy
NSDate NSString 格式化为 ISO8601: "YYYY-MM-dd'T'HH:mm:ssZ"
NSValue struct (CGRect,CGSize,...)
NSNull nil,0
"no","false",... @(NO),0
"yes","true",... @(YES),1

多样化的数据类型交换

YYModel支持自定义的属性名进行映射,即数据的key和属性名可以是不相同。那么怎么才知道你自定义的属性名对应的是数据的哪个key呢?那就需要对自定义属性的映射进行映射声明。

objectivec 复制代码
+ (NSDictionary *)modelCustomPropertyMapper {
   // 将personId映射到key为id的数据字段
    return @{@"personId":@"id"};
}

可以看到model和JSON获取的字典内容并不完全相同,这时候需要我们重写modelCustomPropertyMapper这个方法,使用一个字典将Model属性名对映射到 JSON 的 Key。这就是映射声明。

objectivec 复制代码
+ (NSDictionary *)modelCustomPropertyMapper {
   // 映射可以设定多个映射字段
   return @{@"realComments":@[@"long_comments",@"comments",@"short_comments"]};
}
objectivec 复制代码
// ViewController.m
Model *model = [Model modelWithDictionary:dic];
NSLog(@"realComments: %d",model.realComments);

你可以把一个或一组 json key (key path) 映射到一个或多个属性。如果一个属性没有映射关系,那默认会使用相同属性名作为映射。

在 json->model 的过程中:如果一个属性对应了多个 json key,那么转换过程会按顺序查找,并使用第一个不为空的值。

在 model->json 的过程中:如果一个属性对应了多个 json key (key path),那么转换过程仅会处理第一个 json key (key path);如果多个属性对应了同一个 json key,则转换过过程会使用其中任意一个不为空的值。


容器类数据交换

需要注意:要遵从< YYModel>协议,才会快捷提醒以下方法:

objectivec 复制代码
+ (nullable NSDictionary<NSString *, id> *)modelContainerPropertyGenericClass;
+ (nullable NSDictionary<NSString *, id> *)modelCustomPropertyMapper;
+ (nullable NSArray<NSString *> *)modelPropertyWhitelist;
+ (nullable NSArray<NSString *> *)modelPropertyBlacklist;

如果Model是用一个容器类进行包装的话,我们就需要重写modelContainerPropertyGenericClass这个方法返回对应容器之中的Model类型

objectivec 复制代码
JSON:
{
  "date": "20241020",
  "stories": [
    {
      "image_hue": "0xaa7246",
      "title": "小事 ·「谢谢,这歌儿真好听,谢谢。」",
      "url": "https://daily.zhihu.com/story/9776246",
      "hint": "VOL.1594",
      "ga_prefix": "102007",
      "images": [
        "https://pica.zhimg.com/v2-36a74af2cbeb2950e23f4a21ae7c9afc.jpg?source=8673f162"
      ],
      "type": 0,
      "id": 9776246
    },
    {
      "image_hue": "0x3d342b",
      "title": "很多人都认为大学知识跟高中没有关系,那为什么还要上高中呢?为什么不能初中毕业直接上大学?",
      "url": "https://daily.zhihu.com/story/9776259",
      "hint": "荆公门下东坡首徒 · 10 分钟阅读",
      "ga_prefix": "102007",
      "images": [
        "https://picx.zhimg.com/v2-f1f397a7fa6a1062bee7edd106c49496.jpg?source=8673f162"
      ],
      "type": 0,
      "id": 9776259
    },
    {
      "image_hue": "0x3d342b",
      "title": "武松血溅鸳鸯楼时,张都监的手下为什么不来帮忙?",
      "url": "https://daily.zhihu.com/story/9776265",
      "hint": "娃娃鱼 · 6 分钟阅读",
      "ga_prefix": "102007",
      "images": [
        "https://picx.zhimg.com/v2-f1f397a7fa6a1062bee7edd106c49496.jpg?source=8673f162"
      ],
      "type": 0,
      "id": 9776265
    },
    {
      "image_hue": "0x3d342b",
      "title": "这世界上最毒的物质是什么?",
      "url": "https://daily.zhihu.com/story/9776272",
      "hint": "mekdull · 47 分钟阅读",
      "ga_prefix": "102007",
      "images": [
        "https://picx.zhimg.com/v2-f1f397a7fa6a1062bee7edd106c49496.jpg?source=8673f162"
      ],
      "type": 0,
      "id": 9776272
    }
  ],
  "top_stories": [
    {
      "image_hue": "0x42535e",
      "hint": "作者 / 赵学浩",
      "url": "https://daily.zhihu.com/story/9776126",
      "image": "https://picx.zhimg.com/v2-00604b295890258d35108f32921dfdf2.jpg?source=8673f162",
      "title": "《封神演义》为什么没有列入四大名著?",
      "ga_prefix": "101607",
      "type": 0,
      "id": 9776126
    },
    {
      "image_hue": "0xaa7246",
      "hint": "作者 / 田可乐",
      "url": "https://daily.zhihu.com/story/9776246",
      "image": "https://picx.zhimg.com/v2-520eb91c117bf9da4f62071961629b85.jpg?source=8673f162",
      "title": "小事 ·「谢谢,这歌儿真好听,谢谢。」",
      "ga_prefix": "102007",
      "type": 0,
      "id": 9776246
    },
    {
      "image_hue": "0x8e6238",
      "hint": "作者 / 赵泠",
      "url": "https://daily.zhihu.com/story/9776243",
      "image": "https://picx.zhimg.com/v2-e10faf6e06d42ddaae06fc8dc6e648b8.jpg?source=8673f162",
      "title": "人类以外的动物有没有把自己的食物驯化得好吃的行为?",
      "ga_prefix": "101907",
      "type": 0,
      "id": 9776243
    },
    {
      "image_hue": "0x1a1b37",
      "hint": "作者 / 朱锦平",
      "url": "https://daily.zhihu.com/story/9776238",
      "image": "https://pic1.zhimg.com/v2-5ea4434e6ba5a4e1810059ae1c6c052e.jpg?source=8673f162",
      "title": "黑洞周围的「事件视界」是什么?",
      "ga_prefix": "101807",
      "type": 0,
      "id": 9776238
    },
    {
      "image_hue": "0xb39e74",
      "hint": "作者 / 南行兮",
      "url": "https://daily.zhihu.com/story/9776232",
      "image": "https://picx.zhimg.com/v2-aaa227e7ccc5781303cc1d8e885b9768.jpg?source=8673f162",
      "title": "我为什么总觉得辛弃疾用典的词写的很一般,而不用典的写的很好?",
      "ga_prefix": "101707",
      "type": 0,
      "id": 9776232
    }
  ]
}


@class Stories, Top_stories;

@interface Model
@property NSString *date;
@property NSArray *stories; 
@property NSArray *top_stories; 
@end

@implementation Model
// 返回容器类中的所需要存放的数据类型 (以 Class 或 Class Name 的形式)。
+ (NSDictionary *)modelContainerPropertyGenericClass {
    return @{@"stories" : [stories class],
             @"top_stories" : top_stories.class,
}
@end

打印结果:

objectivec 复制代码
{
    date = 20241021;
    stories =     (
                {
            "ga_prefix" = 102107;
            hint = "\U8c46\U5b50 \U00b7 2 \U5206\U949f\U9605\U8bfb";
            id = 9775499;
            "image_hue" = 0x5d6341;
            images =             (
                "https://pic1.zhimg.com/v2-241803af186704cf830cb0a3ad9268d2.jpg?source=8673f162"
            );
            title = "\U5728\U4e2d\U56fd\U53e4\U4ee3\Uff0c\U7834\U4ea7\U7684\U7537\U4eba\U7684\U4f8d\U59be\U5982\U4f55\U81ea\U5904\Uff1f";
            type = 0;
            url = "https://daily.zhihu.com/story/9775499";
        },
                {
            "ga_prefix" = 102107;
            hint = "\U674e\U7965JasonLee \U00b7 3 \U5206\U949f\U9605\U8bfb";
            id = 9776310;
            "image_hue" = 0x261e1b;
            images =             (
                "https://picx.zhimg.com/v2-aa2257309051a31b36501c840bf8cfaa.jpg?source=8673f162"
            );
            title = "\U4e4b\U524d\U542c\U8bf4\U589e\U808c\U8981\U505a\U5230\U529b\U7aed\Uff0c\U4e3a\U4ec0\U4e48\U73b0\U5728\U53c8\U63d0\U5021\U300c\U4e0d\U529b\U7aed\U300d\U4e86\Uff1f";
            type = 0;
            url = "https://daily.zhihu.com/story/9776310";
        },
                {
            "ga_prefix" = 102107;
            hint = "\U859b\U52a8\U8c14\U7684\U55b5 \U00b7 3 \U5206\U949f\U9605\U8bfb";
            id = 9776311;
            "image_hue" = 0x191924;
            images =             (
                "https://pic1.zhimg.com/v2-3673082d8ee90b155a4ecd2b556954a4.jpg?source=8673f162"
            );
            title = "\U8bba\U6587\U5e38\U7528\U8bcd\U6c47 i.e.\Uff0ce.g.\Uff0cetc.\Uff0cviz.\Uff0cet al. \U7684\U524d\U4e16\U4eca\U751f";
            type = 0;
            url = "https://daily.zhihu.com/story/9776311";
        },
                {
            "ga_prefix" = 102106;
            hint = "VOL.3454";
            id = 9776346;
            "image_hue" = 0xb3b3b3;
            images =             (
                "https://pic1.zhimg.com/v2-b8a38efaf99a864356cef394c26becc0.jpg?source=8673f162"
            );
            title = "\U778e\U626f \U00b7 \U5982\U4f55\U6b63\U786e\U5730\U5410\U69fd";
            type = 0;
            url = "https://daily.zhihu.com/story/9776346";
        }
    );
    "top_stories" =     (
                {
            "ga_prefix" = 101607;
            hint = "\U4f5c\U8005 / \U8d75\U5b66\U6d69";
            id = 9776126;
            image = "https://picx.zhimg.com/v2-00604b295890258d35108f32921dfdf2.jpg?source=8673f162";
            "image_hue" = 0x42535e;
            title = "\U300a\U5c01\U795e\U6f14\U4e49\U300b\U4e3a\U4ec0\U4e48\U6ca1\U6709\U5217\U5165\U56db\U5927\U540d\U8457\Uff1f";
            type = 0;
            url = "https://daily.zhihu.com/story/9776126";
        },
                {
            "ga_prefix" = 102007;
            hint = "\U4f5c\U8005 / \U7530\U53ef\U4e50";
            id = 9776246;
            image = "https://picx.zhimg.com/v2-520eb91c117bf9da4f62071961629b85.jpg?source=8673f162";
            "image_hue" = 0xaa7246;
            title = "\U5c0f\U4e8b \U00b7\U300c\U8c22\U8c22\Uff0c\U8fd9\U6b4c\U513f\U771f\U597d\U542c\Uff0c\U8c22\U8c22\U3002\U300d";
            type = 0;
            url = "https://daily.zhihu.com/story/9776246";
        },
                {
            "ga_prefix" = 101907;
            hint = "\U4f5c\U8005 / \U8d75\U6ce0";
            id = 9776243;
            image = "https://picx.zhimg.com/v2-e10faf6e06d42ddaae06fc8dc6e648b8.jpg?source=8673f162";
            "image_hue" = 0x8e6238;
            title = "\U4eba\U7c7b\U4ee5\U5916\U7684\U52a8\U7269\U6709\U6ca1\U6709\U628a\U81ea\U5df1\U7684\U98df\U7269\U9a6f\U5316\U5f97\U597d\U5403\U7684\U884c\U4e3a\Uff1f";
            type = 0;
            url = "https://daily.zhihu.com/story/9776243";
        },
                {
            "ga_prefix" = 101807;
            hint = "\U4f5c\U8005 / \U6731\U9526\U5e73";
            id = 9776238;
            image = "https://pic1.zhimg.com/v2-5ea4434e6ba5a4e1810059ae1c6c052e.jpg?source=8673f162";
            "image_hue" = 0x1a1b37;
            title = "\U9ed1\U6d1e\U5468\U56f4\U7684\U300c\U4e8b\U4ef6\U89c6\U754c\U300d\U662f\U4ec0\U4e48\Uff1f";
            type = 0;
            url = "https://daily.zhihu.com/story/9776238";
        },
                {
            "ga_prefix" = 101707;
            hint = "\U4f5c\U8005 / \U5357\U884c\U516e";
            id = 9776232;
            image = "https://picx.zhimg.com/v2-aaa227e7ccc5781303cc1d8e885b9768.jpg?source=8673f162";
            "image_hue" = 0xb39e74;
            title = "\U6211\U4e3a\U4ec0\U4e48\U603b\U89c9\U5f97\U8f9b\U5f03\U75be\U7528\U5178\U7684\U8bcd\U5199\U7684\U5f88\U4e00\U822c\Uff0c\U800c\U4e0d\U7528\U5178\U7684\U5199\U7684\U5f88\U597d\Uff1f";
            type = 0;
            url = "https://daily.zhihu.com/story/9776232";
        }
    );
}

model中包含其他model

仅需让一个model属性包含另一个model即可。

objectivec 复制代码
// JSON
{
    "memory ":{
        "name":"lfc",
        "birthday":"2023-07-26"
    },
    "name":"yl",
    "age":17
}
 
// Model: 什么都不用做,转换会自动完成
@interface Memory : NSObject
@property NSString *name;
@property NSDate *birthday;
@end
@implementation Memory 
@end
 
@interface People : NSObject
@property NSString *name;
@property NSUInteger age;
@property Author *author; //People 包含 Memory  属性
@end
@implementation People
@end

白名单与黑名单

注意:黑白名单不同时使用

objectivec 复制代码
+ (NSArray<NSString *> *)modelPropertyBlacklist {
    return @[@"Memory"];
}//这个方法不会处理JSON数据中的这个数据
+ (NSArray<NSString *> *)modelPropertyWhitelist {
    return @[@"Memory"];
}//这个方法会让程序只处理JSON中的这个数据

总结

对YYModel的简单学习,后续还会对源码进行学习。

相关推荐
future14121 小时前
游戏开发日记
数据结构·学习·c#
棱镜研途2 小时前
学习笔记丨卷积神经网络(CNN):原理剖析与多领域Github应用
图像处理·笔记·学习·计算机视觉·cnn·卷积神经网络·信号处理
皮蛋sol周3 小时前
嵌入式学习C语言(八)二维数组及排序算法
c语言·学习·算法·排序算法
人生游戏牛马NPC1号4 小时前
学习 Flutter (一)
android·学习·flutter
fundroid4 小时前
Swift 进军 Android,Kotlin 该如何应对?
android·ios
Aczone284 小时前
嵌入式 数据结构学习 (六) 树、哈希表与内核链表
数据结构·学习·算法
想成为大佬的每一天5 小时前
Linux驱动学习day22(interrupt子系统)
学习
Chef_Chen5 小时前
从0开始学习R语言--Day43--Wald检验
学习
真的想上岸啊5 小时前
学习C++、QT---21(QT中QFile库的QFile读取文件、写入文件的讲解)
c++·qt·学习
之歆5 小时前
Python-正则表达式-信息提取-滑动窗口-数据分发-文件加载及分析器-浏览器分析-学习笔记
python·学习·正则表达式