YYModel 源码解读(二)之YYClassInfo.h (1)
NS_ASSUME_NONNULL_BEGIN
NS_ASSUME_NONNULL_END
为了兼容Swift 中的 ? 和 ! oc 在6.3引入了两个新的类型注释:__nullable和__nonnull , 在字面上很好理解 可能为空, 不为空,
在上面代码中间则表示 默认的所有的属性都不能为空,这样我们在敲码的过程中只需要手写__nullable的类型就可以了
/**
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
};
上边的代码 就涉及到了运行时中的类型解码方面的知识了,在此总结一下
关于Type Encodings 的官方解释 , @encode 是一个编译器指令,返回个内部表示的字符串 , 比如: @encode(int)
→ i ,作用就是可以加快运行时库的消息分发,
需要注意的是:
- 指针的标准编码是加一个前置的
^
,而char *
拥有自己的编码*
。这在概念上是很好理解的,因为 C 的字符串被认为是一个实体,而不是指针。 BOOL
是c
,而不是某些人以为的i
。原因是char
比int
小,且在 80 年代 Objective-C 最开始设计的时候,每一个 bit 位都比今天的要值钱(就像美元一样)。BOOL
更确切地说是signed char
(即使设置了-funsigned-char
参数),以在不同编译器之间保持一致,因为char
可以是signed
或者unsigned
。- 直接传入
NSObject
将产生#
。但是传入[NSObject class]
产生一个名为NSObject
只有一个类字段的结构体。很明显,那就是isa
字段,所有的NSObject
实例都用它来表示自己的类型。
通过打印的数据,看起来更加直观
NSLog(@"int : %s", @encode(int));
NSLog(@"float : %s", @encode(float));
NSLog(@"float * : %s", @encode(float*));
NSLog(@"char : %s", @encode(char));
NSLog(@"char * : %s", @encode(char *));
NSLog(@"BOOL : %s", @encode(BOOL));
NSLog(@"void : %s", @encode(void));
NSLog(@"void * : %s", @encode(void *)); NSLog(@"NSObject * : %s", @encode(NSObject *));
NSLog(@"NSObject : %s", @encode(NSObject));
NSLog(@"[NSObject] : %s", @encode(typeof([NSObject class])));
NSLog(@"NSError ** : %s", @encode(typeof(NSError **))); int intArray[] = {, , , , };
NSLog(@"int[] : %s", @encode(typeof(intArray))); float floatArray[] = {0.1f, 0.2f, 0.3f};
NSLog(@"float[] : %s", @encode(typeof(floatArray))); typedef struct _struct {
short a;
long long b;
unsigned long long c;
} Struct;
NSLog(@"struct : %s", @encode(typeof(Struct)));
-- ::00.172 ModelBenchmark[:] int : i
-- ::00.173 ModelBenchmark[:] float : f
-- ::00.173 ModelBenchmark[:] float * : ^f
-- ::00.173 ModelBenchmark[:] char : c
-- ::00.173 ModelBenchmark[:] char * : *
-- ::00.173 ModelBenchmark[:] BOOL : B
-- ::00.174 ModelBenchmark[:] void : v
-- ::00.174 ModelBenchmark[:] void * : ^v
-- ::00.174 ModelBenchmark[:] NSObject * : @
-- ::00.174 ModelBenchmark[:] NSObject : {NSObject=#}
-- ::00.174 ModelBenchmark[:] [NSObject] : #
-- ::00.174 ModelBenchmark[:] NSError ** : ^@
-- ::00.174 ModelBenchmark[:] int[] : [5i]
-- ::00.174 ModelBenchmark[:] float[] : [3f]
-- ::00.174 ModelBenchmark[:] struct : {_struct=sqQ}
关于 Type Property 和 Functions 的官方解释 ,可以参考官方文档获取编译后的内容
YYEncodingType YYEncodingGetType(const char *typeEncoding);
定义一个方法 把typeEncoding 转为自定义的枚举类型,方便管理和使用,
YYEncodingType YYEncodingGetType(const char *typeEncoding) { // 判断外部传入值 是不是nil,如果为空 ,返回 YYEncodingTypeUnknown
// 转换const 限定符
char *type = (char *)typeEncoding;
if (!type) return YYEncodingTypeUnknown;
size_t len = strlen(type);
if (len == ) return YYEncodingTypeUnknown; // 找出修饰语
YYEncodingType qualifier = ;
bool prefix = true; // 可能多个修饰符
while (prefix) { switch (*type) {
case 'r': {
qualifier |= YYEncodingTypeQualifierConst;
type++;
} break;
case 'n': {
qualifier |= YYEncodingTypeQualifierIn;
type++;
} break;
case 'N': {
qualifier |= YYEncodingTypeQualifierInout;
type++;
} break;
case 'o': {
qualifier |= YYEncodingTypeQualifierOut;
type++;
} break;
case 'O': {
qualifier |= YYEncodingTypeQualifierBycopy;
type++;
} break;
case 'R': {
qualifier |= YYEncodingTypeQualifierByref;
type++;
} break;
case 'V': {
qualifier |= YYEncodingTypeQualifierOneway;
type++;
} break;
default: { prefix = false; } break;
}
} // 是否还存在后续的字符
len = strlen(type);
if (len == ) return YYEncodingTypeUnknown | qualifier; // 查找数据类型
switch (*type) {
case 'v': return YYEncodingTypeVoid | qualifier;
case 'B': return YYEncodingTypeBool | qualifier;
case 'c': return YYEncodingTypeInt8 | qualifier;
case 'C': return YYEncodingTypeUInt8 | qualifier;
case 's': return YYEncodingTypeInt16 | qualifier;
case 'S': return YYEncodingTypeUInt16 | qualifier;
case 'i': return YYEncodingTypeInt32 | qualifier;
case 'I': return YYEncodingTypeUInt32 | qualifier;
case 'l': return YYEncodingTypeInt32 | qualifier;
case 'L': return YYEncodingTypeUInt32 | qualifier;
case 'q': return YYEncodingTypeInt64 | qualifier;
case 'Q': return YYEncodingTypeUInt64 | qualifier;
case 'f': return YYEncodingTypeFloat | qualifier;
case 'd': return YYEncodingTypeDouble | qualifier;
case 'D': return YYEncodingTypeLongDouble | qualifier;
case '#': return YYEncodingTypeClass | qualifier;
case ':': return YYEncodingTypeSEL | qualifier;
case '*': return YYEncodingTypeCString | qualifier;
case '^': return YYEncodingTypePointer | qualifier;
case '[': return YYEncodingTypeCArray | qualifier;
case '(': return YYEncodingTypeUnion | qualifier;
case '{': return YYEncodingTypeStruct | qualifier;
case '@': {
if (len == && *(type + ) == '?')
return YYEncodingTypeBlock | qualifier;
else
return YYEncodingTypeObject | qualifier;
}
default: return YYEncodingTypeUnknown | qualifier;
}
}
上边的方法 主要是找出所有的和属性相关的信息,并转换为自定义的类型
YYModel 源码解读(二)之YYClassInfo.h (1)的更多相关文章
- YYModel 源码解读(二)之NSObject+YYModel.h (1)
本篇文章主要介绍 _YYModelPropertyMeta 前边的内容 首先先解释一下前边的辅助函数和枚举变量,在写一个功能的时候,这些辅助的东西可能不是一开始就能想出来的,应该是在后续的编码过程中 ...
- jQuery.Callbacks 源码解读二
一.参数标记 /* * once: 确保回调列表仅只fire一次 * unique: 在执行add操作中,确保回调列表中不存在重复的回调 * stopOnFalse: 当执行回调返回值为false,则 ...
- (转)go语言nsq源码解读二 nsqlookupd、nsqd与nsqadmin
转自:http://www.baiyuxiong.com/?p=886 ---------------------------------------------------------------- ...
- YYModel 源码解读(二)之YYClassInfo.h (3)
前边3篇介绍了YYClassinfo 文件的组成单元,算是功能的分割,按照业务的设计思想来说,方向应该是相反的 由此引申出我们在设计api的思想其实和项目管理是很类似的----- 一些题外话 1.目的 ...
- YYModel 源码解读(一)之YYModel.h
#if __has_include(<YYModel/YYModel.h>) FOUNDATION_EXPORT double YYModelVersionNumber; FOUNDATI ...
- YYModel 源码解读 总结
在使用swfit写代码的过程中,使用了下oc写的字典转模型,发现有些属性转不成功,就萌生了阅读源码的想法. 其实一直都知道Runtime机制,但并没有系统的学习,可能是因为平时的使用比较少,无意间在g ...
- ConcurrentHashMap源码解读二
接下来就讲解put里面的三个方法,分别是 1.数组初始化方法initTable() 2.线程协助扩容方法helpTransfer() 3.计数方法addCount() 首先是数组初始化,再将源码之前, ...
- mybatis源码解读(二)——构建Configuration对象
Configuration 对象保存了所有mybatis的配置信息,主要包括: ①. mybatis-configuration.xml 基础配置文件 ②. mapper.xml 映射器配置文件 1. ...
- ROS源码解读(二)--全局路径规划
博客转载自:https://blog.csdn.net/xmy306538517/article/details/79032324 ROS中,机器人全局路径规划默认使用的是navfn包 ,move_b ...
- go语言nsq源码解读二 nsqlookupd、nsqd与nsqadmin
nsqlookupd: 官方文档解释见:http://bitly.github.io/nsq/components/nsqlookupd.html 用官方话来讲是:nsqlookupd管理拓扑信息,客 ...
随机推荐
- SQL Server 数据加密功能解析
SQL Server 数据加密功能解析 转载自: 腾云阁 https://www.qcloud.com/community/article/194 数据加密是数据库被破解.物理介质被盗.备份被窃取的最 ...
- BIOS中未启用虚拟化支持系列~~例如:因此无法安装Hyper-V
异常处理汇总-服务器系列:http://www.cnblogs.com/dunitian/p/4522983.html 一般都是启动一下CUP虚拟化就可以了 比如华硕的:
- [C#][算法] 用菜鸟的思维学习算法 -- 马桶排序、冒泡排序和快速排序
用菜鸟的思维学习算法 -- 马桶排序.冒泡排序和快速排序 [博主]反骨仔 [来源]http://www.cnblogs.com/liqingwen/p/4994261.html 目录 马桶排序(令人 ...
- Android Notification 详解——基本操作
Android Notification 详解 版权声明:本文为博主原创文章,未经博主允许不得转载. 前几天项目中有用到 Android 通知相关的内容,索性把 Android Notificatio ...
- JQuery中的siblings()是什么意思
jQuery siblings() 方法返回被选元素的所有同胞元素,并且可以使用可选参数来过滤对同胞元素的搜索. 实例演示:点击某个li标签后将其设置为红色,而其所有同胞元素去除红色样式. 1.创建H ...
- 【干货分享】流程DEMO-事务呈批表
流程名: 事务呈批表 业务描述: 办公采购.会议费用等事务的申请.流程发起时,会检查预算,如果预算不够,将不允许发起费用申请,如果预算够用,将发起流程,同时占用相应金额的预算,但撤销流程会释放相应金 ...
- Zabbix 漏洞分析
之前看到Zabbix 出现SQL注入漏洞,自己来尝试分析. PS:我没找到3.0.3版本的 Zabbix ,暂用的是zabbix 2.2.0版本,如果有问题,请大牛指点. 0x00 Zabbix简介 ...
- SEED实验系列文章目录
美国雪城大学SEEDLabs实验列表 SEEDLabs是一套完整的信息安全实验,涵盖本科信息安全教学中的大部分基本原理.项目组2002年由杜文亮教授创建,目前开发了30个实验,几百所大学已采用.实验楼 ...
- Jexus 服务器部署导航
说明:本索引只是方便本人查找,不涉及版权问题,所有博客,还是到元博客地址访问. <script async src="//pagead2.googlesyndication.com/p ...
- 【腾讯Bugly干货分享】跨平台 ListView 性能优化
本文来自于腾讯Bugly公众号(weixinBugly),未经作者同意,请勿转载,原文地址:https://mp.weixin.qq.com/s/FbiSLPxFdGqJ00WgpJ94yw 导语 精 ...