iOS类型编码Type Encodings与属性类型Property Type
来源:互联网 发布:vincizhang淘宝上有吗 编辑:程序博客网 时间:2024/05/16 14:29
关于runtime的文章中多次提到了类型编码,下边说说类型编码到底是什么鬼。
相关链接:
官方文档一
官方文档二
YYModel 源码历险记<二> 关于变量类型和编码
类型编码(Type Encodings)
类型编码(Type Encoding)
作为对Runtime的补充,编译器将每个方法的返回值和参数类型编码为一个字符串,并将其与方法的selector关联在一起。这种编码方案在其它情况下也是非常有用的,因此我们可以使用@encode编译器指令来获取它。当给定一个类型时,@encode返回这个类型的字符串编码。这些类型可以是诸如int、指针这样的基本类型,也可以是结构体、类等类型。事实上,任何可以作为sizeof()操作参数的类型都可以用于@encode()。
char *buf1 = @encode(int **);char *buf2 = @encode(struct key);char *buf3 = @encode(Rectangle);
下表列出了类型代码。注意,当编码一个对象用于归档或分配时,有许多代码时重叠的。然而,在编写编码器时,这里有些代码不能使用。也有些代码可以使用,但不是@encode()所产生的。(关于编码对象的归档和分配的更多信息,可见基础框架引用中NSCode类规范。)
char *buf1 = @encode(int); char *buf2 = @encode(char); char *buf3 = @encode(long double); char *buf4 = @encode(void); char *buf5 = @encode(Class); char *buf6 = @encode(id); char *buf7 = @encode(char *); char *buf8 = @encode(NSArray *);
输出为:
重要:Objective-C 不支持long double 类型。@encode(long double) 返回d,和double编码一样。
数组类型代码是包含在方括号中,在开括号后,数组类型前指定数组中元素的个数。例如,
float a[] = {1.0, 2.0, 3.0};NSLog(@"array encoding type: %s", @encode(typeof(a)));
输出: array encoding type: [3f]
结构在括号中指定,在圆括号中结合。最先列出结构标记,然后是等号和序列中列出的结构的范围代码
typedef struct example { id anObject; char *aString; int anInt; } Example;
结构编码如下:
{example=@*i}
对象被当做结构。例如,传递NSObject类名到@encode() 产生如下编码:
{NSObject=#}
NSObject类声明一个实例变量,isa,作为类型类。
注意:尽管@encode()指令不返回它们,在协议中用来声明方法时,运行时系统使用表6-2中列出的额外编码列表来限定类型。
属性类型Property Type
苹果对每一个变量的类型进行了编码,对方法的类型也进行了编码,于是我们获取到变量的attributes时,就是经过编译器编码后得到的属性。
我们来写个方法打印下看看到底是什么鬼?
+ (NSArray *)properties1{ NSArray *propertiesArray = [NSMutableArray array]; // 1.获得所有的属性 unsigned int outCount = 0; objc_property_t *properties = class_copyPropertyList(self, &outCount); for (int i = 0; i < outCount; i++) { objc_property_t property = properties[i]; NSLog(@"name:%s---attributes:%s",((propertyStruct)property)->name,((propertyStruct)property)->attributes); //事实上苹果已经给出了我们获取属性attributes的方法// property_getAttributes(property);// property_getName(property); } return propertiesArray;}
objc_property_t *properties
的原型大概就是这个样子:
typedef struct property_t { const char *name; const char *attributes;} *propertyStruct;
所以我们可以用这个方法去获取到属性的名字和描述。打印结果如下:
2016-09-01 17:38:29.726 RuntimeDemo[45809:23195325] name:name---attributes:T@"NSString",C,N,V_name2016-09-01 17:38:29.726 RuntimeDemo[45809:23195325] name:age---attributes:Ti,N,V_age2016-09-01 17:38:29.726 RuntimeDemo[45809:23195325] name:father---attributes:T@"NSString",C,N,V_father2016-09-01 17:38:29.727 RuntimeDemo[45809:23195325] name:secondModel---attributes:T@"DDSecondModel",&,N,V_secondModel2016-09-01 17:38:29.727 RuntimeDemo[45809:23195325] name:thirdModel---attributes:T@"NSArray",&,N,V_thirdModel
NSLog打印的结果可能有点不一样,其实原型是这样的:
"T@\"NSArray\",&,N,V_thirdModel"
中间会多一个@\,这牵扯到c与oc的转换,在OC字符串中 \” -> “,\是转义的意思,不占用字符
我们试着来看懂一个编码的类型,首先这个T@”NSArray”指的这个变量是NSArray类型,&代表的是retain的在ARC状态下也就是strong类型,N表示的是是nonatomic的,V_thirdModel代表这个变量名是thirdModel,再来看看我们的声明,好像是并不是那么难懂,再来查一查官方文档,对这些字符进行了定义:
官方文档又给出了一些例子:
enum FooManChu { FOO, MAN, CHU };struct YorkshireTeaStruct { int pot; char lady; };typedef struct YorkshireTeaStruct YorkshireTeaStructType;union MoneyUnion { float alone; double down; };
文章开头给出了官方文档地址,可以再去看看。
- iOS类型编码Type Encodings与属性类型Property Type
- iOS 类型编码(Type Encodings)
- iOS 类型编码 Type Encodings 详解
- 类型编码(Type Encodings)
- iOS Type Encodings
- Type Encodings
- input元素属性type类型
- Type “”类型“”
- 关于iOS中的type encodings 和method encodings
- wrapped type与primitive type 包装类型与原始类型
- 列表样式类型属性(list-style-type)
- 列表样式类型属性(list-style-type)
- jquery源码之属性判断-$.type类型
- 自定义结果类型(result的type属性)
- result的type属性中有哪几种结果类型?
- Objective-C type encodings
- Type Encodings property_getAttributes
- Type Encodings-runtime
- Android OTA升级的补救措施
- Run Loops
- caffe源码vision_layers.hpp+各cpp
- FFmpeg视频编解码库,无法解析的外部信号
- ubunbut下文字转图片报错, convert : unable to read font
- iOS类型编码Type Encodings与属性类型Property Type
- iOS钥匙串返回-50
- SQL的内连接与外连接
- android 流布局 FlowLayout
- Map遍历方式
- TensorFlow入门教程集合
- iOS积分抽奖Demo,可以人为控制不同奖项的得奖率
- 背包九讲之01背包问题
- mysql计算时间差