六、Runtime 实践部分 之 YYModel 源码跟读

本文github地址 https://github.com/ICZhuang/Runtime 朋友们如果喜欢收藏即可,不建议转载,笔者会不定期update文章,github 也会同步更新,喜欢就star一下吧。

想着继续介绍Runtime 的概念部分 关于Protocol,Category,还有objc_xxx API,但又想到这跟之前介绍的都有相通的地方,所以就不再拉长篇幅了。其中就“关联对象”还需要提一下,然而网络博客已经一大堆了,有些东西,毕竟没有去实际应用过,不好做总结,就在真正用到Runtime再详细的补上吧。

MJExtension 和 YYKit中的模型对象互转,是Runtime体现出目前最为广泛使用的方式之一。至于这里选择读YYKit没什么特殊原因,就是因为项目中使用的是YYKit,我想,看懂一个,在去看懂另外一个不是难事儿。。

YYClassInfo

看头文件,就知道,这个就是在获取一个类中的各部分的信息。该头文件声明了四个类YYClassInfo、YYClassPropertyInfo、 YYClassIvarInfo、YYClassMethodInfo,它们就是对应着将objc_class、objc_property、objc_ivar、objc_method封装成OC对象。

YYClassInfo的核心方法就是_update方法,在这个方法里,遍历class对象的各个部分,将它们封装成了对象放进属性中。

笔者认为,在有了前面的基础,看懂这个方法在做什么绝不是难事,这里笔者只提一下本人认为的比较巧妙的方法。就是对类型编码的处理方法。

YYEncodingType YYEncodingGetType(const char *typeEncoding);

关于类型编码,可参考官方文档

‘Objective-C Runtime Programming Guide > Type Encodings’

‘Objective-C Runtime Programming Guide > Declared Properties’

笔者译文 Type Encoding & Declared Propery

对编码的处理,YY大神将其字符串表示的编码转成用枚举标识,而理解的关键点也就在于枚举的运算,就是枚举的 &、| 操作。另外有一点需要知晓的是使用过的Class info会被缓存的。

在 Type Encodings 文档中谈及的有 类型编码和类型描述符编码,而在 Declared Properties 文档中谈及的则有访问属性的attribute的编码。关于这三类编码都在头文件中 YYEncodingType 的枚举中对应找到,YYKit就是将 C 字符串的形式转成用枚举来表示类型编码。

/**
 Type encoding's type.
 */
typedef NS_OPTIONS(NSUInteger, YYEncodingType) {
    YYEncodingTypeMask       = 0xFF, ///< mask of type value
    YYEncodingTypeUnknown    = 0, ///< unknown
    YYEncodingTypeVoid       = 1, ///< void
    YYEncodingTypeBool       = 2, ///< bool
    YYEncodingTypeInt8       = 3, ///< char / BOOL
    YYEncodingTypeUInt8      = 4, ///< unsigned char
    YYEncodingTypeInt16      = 5, ///< short
    YYEncodingTypeUInt16     = 6, ///< unsigned short
    YYEncodingTypeInt32      = 7, ///< int
    YYEncodingTypeUInt32     = 8, ///< unsigned int
    YYEncodingTypeInt64      = 9, ///< long long
    YYEncodingTypeUInt64     = 10, ///< unsigned long long
    YYEncodingTypeFloat      = 11, ///< float
    YYEncodingTypeDouble     = 12, ///< double
    YYEncodingTypeLongDouble = 13, ///< long double
    YYEncodingTypeObject     = 14, ///< id
    YYEncodingTypeClass      = 15, ///< Class
    YYEncodingTypeSEL        = 16, ///< SEL
    YYEncodingTypeBlock      = 17, ///< block
    YYEncodingTypePointer    = 18, ///< void*
    YYEncodingTypeStruct     = 19, ///< struct
    YYEncodingTypeUnion      = 20, ///< union
    YYEncodingTypeCString    = 21, ///< char*
    YYEncodingTypeCArray     = 22, ///< char[10] (for example)
    
    YYEncodingTypeQualifierMask   = 0xFF00,   ///< mask of qualifier
    YYEncodingTypeQualifierConst  = 1 << 8,  ///< const
    YYEncodingTypeQualifierIn     = 1 << 9,  ///< in
    YYEncodingTypeQualifierInout  = 1 << 10, ///< inout
    YYEncodingTypeQualifierOut    = 1 << 11, ///< out
    YYEncodingTypeQualifierBycopy = 1 << 12, ///< bycopy
    YYEncodingTypeQualifierByref  = 1 << 13, ///< byref
    YYEncodingTypeQualifierOneway = 1 << 14, ///< oneway
    
    YYEncodingTypePropertyMask         = 0xFF0000, ///< mask of property
    YYEncodingTypePropertyReadonly     = 1 << 16, ///< readonly
    YYEncodingTypePropertyCopy         = 1 << 17, ///< copy
    YYEncodingTypePropertyRetain       = 1 << 18, ///< retain
    YYEncodingTypePropertyNonatomic    = 1 << 19, ///< nonatomic
    YYEncodingTypePropertyWeak         = 1 << 20, ///< weak
    YYEncodingTypePropertyCustomGetter = 1 << 21, ///< getter=
    YYEncodingTypePropertyCustomSetter = 1 << 22, ///< setter=
    YYEncodingTypePropertyDynamic      = 1 << 23, ///< @dynamic
};

很明显了,最上面YYEncodingTypexxx 是代表变量的类型编码,YYEncodingTypeQualifierxxx 是代表类型修饰符编码,YYEncodingTypePropertyxxx 则是代表属性的 attributes 的编码。其中属性的 attributes 的编码处理在YYPropertyInfo初始化的时候就已经处理了,YYEncodingGetType 这个方法只是用来处理类型的编码。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,383评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,522评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,852评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,621评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,741评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,929评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,076评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,803评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,265评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,582评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,716评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,395评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,039评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,027评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,488评论 2 361
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,612评论 2 350

推荐阅读更多精彩内容

  • 对于从事 iOS 开发人员来说,所有的人都会答出【runtime 是运行时】什么情况下用runtime?大部分人能...
    梦夜繁星阅读 3,700评论 7 64
  • 前言 Runtime是iOS开发者进阶必须学习的一个知识点。网上关于Runtime 有许多介绍,有深入有简单介绍,...
    雨田_Toping阅读 1,568评论 1 1
  • 转至元数据结尾创建: 董潇伟,最新修改于: 十二月 23, 2016 转至元数据起始第一章:isa和Class一....
    40c0490e5268阅读 1,690评论 0 9
  • 赵无极:模特儿里关系很多,你看身体转动关系很多。怎样使它简单,但是里面包含很多东西,并不是复杂就好,好像讲话要中肯...
    swlighter阅读 395评论 0 0
  • 一年下来,发现虽然自己发自内心的热爱教育事业,发自内心的喜欢和孩子们在一起,发自内心的想把每一位孩子教育成才...
    李亚美阅读 171评论 0 2