关于type encodings的理解--runtime programming guide

runtime programming guide

这次准备好好研究下runtime programming, 先从encodings开始了解,这个对于理解oc的类也是很有帮助的。
废话不多说直接开始。

Type Encodings

compiler 编码encode 每个method的返回值,参数类型,将这些信息保存在一个字符串里。然后将这个string和selector关联起来。

这套编码也适用于其他场景,所以这个@encode编译器指令是设计成公开的。当给定一个type的规范声明,@encode()返回相对应的字符串类型编码值。

char *buf1 = @encode(int **);
char *buf2 = @encode(struct key);
char *buf3 = @encode(Rectangle);
type encodings

更多的类型可以查看https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtTypeEncodings.html#//apple_ref/doc/uid/TP40008048-CH100-SW1

数组的type code是一个中括号里面,然后紧接着一个数组个数值和相对应的数组元素的类型,如一个包含12个float指针的数组的编码为:[12^f]

structures 是一个大括号里,里面是显示紧跟着structure tag(struct的结构名称)然后一个等号(equal sign)=,接着就是struct里各个类型排列在一起,比如

typedef struct example {
    id   anObject;
    char *aString;
    int  anInt;
} Example;

的type code值为 {example=@*i}, 如果是一个结构体的指针,那么encode为^{example=@*i},如果是一个结构体的指针的指针,则是^^{example}.

Objects对象也被看成一个struct。@encode(NSObject)结果是{NSObject=#}, 因为NSObject class里就一个isa(class 类型)的变量。

尽管 @encode()不直接返回数据, 但运行时会使用额外的一个encoding列表来表示一些方法声明的后缀修饰符.

code Meaning
r const
i int
N inout
o out
O bycopy
R byref
V oneway

Declared Propertyies

当编译器碰到property声明时,它会生成描述性的带有关于class, category或者protocol的metadata元数据。

你能通过一些列的api函数来访问这个metadata,通过class,protocol上的name来查找property。可以通过@encode来获取property的encode string。可以copy property的attributes list(C strings)。

class和protocol都有一个properties list的值。

property type and functions

可以通过class_copyPropertyList和protocol_copyPropertyList来遍历class(包括loaded categories)和protocol的property list

通过property_getAttributes可以获取到一个property属性的@encode type的值。

比如一个@property (nonatomic, strong) NSString *login;的property @encode值为T@"NSString",&,N,V_login

每个逗号都是分割一个属性attribute,实际上当你获取到objc_property_attribute_t *attrs = property_copyAttributeList(prot, &outcount);(注意你还需要主动free掉attrs) outcount的值就是分割后的数组的个数。

attrs分别为:

property index name value
0 T @"NSString"
1 &
2 N
3 V _login

Property type string

文档里面有一段英文很重要,他描述了property type的string值的格式(这个值可以通过@encode或者通过property_getAttributes来获取)。

You can use the property_getAttributes function to discover the name, the @encode type string of a property, and other attributes of the property.

The string starts with a T followed by the @encode type and a comma, and
finishes with a V followed by the name of the backing instance variable.
Between these, the attributes are specified by the following descriptors, separated by commas:

*** 这段英文很重要,说明了格式,首先是以一个T开头的,然后@encode type加一个逗号,以一个V后面带上存储支持的实例变量,然后在中间,每个attributes都是以逗号隔开的,这些attributes描述如下:***

可以官场上面的那个例子@property (nonatomic, strong) NSString *login;的property @encode值为T@"NSString",&,N,V_login

Table 7-1 Declared property type encodings

Code Meaning
R The property is read-only (readonly).
C The property is a copy of the value last assigned (copy).
& The property is a reference to the value last assigned (retain).
N The property is non-atomic (nonatomic).
G<name> The property defines a custom getter selector name. The name follows the G (for example, GcustomGetter,).
S<name> The property defines a custom setter selector name. The name follows the S (for example, ScustomSetter:,)
D The property is dynamic (@dynamic).
W The property is a weak reference (__weak).
P The property is eligible for garbage collection.
t<encoding> Specifies the type using old-style encoding.

这个链接里有相关的demo示例说明property declaration声明和描述description。
https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtPropertyIntrospection.html#//apple_ref/doc/uid/TP40008048-CH101-SW5

这里只罗列少数几个:

property declaration description
@property(getter=intGetFoo, setter=intSetFoo:) int intSetterGetter; Ti,GintGetFoo,SintSetFoo:,V_intSetterGetter
@property int intSynthEquals;In the implementation block:@synthesize intSynthEquals=_intSynthEquals; Ti,V_intSynthEquals
@property int (*functionPointerDefault)(char *); T^?,V_functionPointerDefault
@property (strong, atomic) NSString * dataObject; T@"NSString",&,V_dataObject

function/method type encode

先看例子:

//- (void)viewWillAppear:(BOOL)animated  -> v20@0:8B16
NSLog(@"%s", class_getInstanceMethod([self class], @selector(viewWillAppear:)));
//- (void) setSomething:(id) anObject  -> v24@0:8@16
NSLog(@"%s", method_getTypeEncoding(class_getInstanceMethod([self class], @selector(setSomething:))));
//- (BOOL) setSomething:(UInt8)animated aa:(id)anObject  -> B28@0:8C16@20
NSLog(@"%s", method_getTypeEncoding(class_getInstanceMethod([self class], @selector(setSomething:aa:))));
//- (BOOL) setSomething:(UInt16)animated aa:(id)anObject  -> B28@0:8s16@20
NSLog(@"%s", method_getTypeEncoding(class_getInstanceMethod([self class], @selector(setSomething:aa:))));
//- (BOOL) setSomething:(int)animated aa:(id)anObject  -> B28@0:8i16@20
NSLog(@"%s", method_getTypeEncoding(class_getInstanceMethod([self class], @selector(setSomething:aa:))));
//- (BOOL) setSomething:(long)animated aa:(id)anObject-> B32@0:8q16@24
NSLog(@"%s", method_getTypeEncoding(class_getInstanceMethod([self class], @selector(setSomething:aa:))));


typedef struct  {
    uint32_t a;
    uint16_t b;
    uint8_t c;
} __attribute__((packed)) MyStruct;
// - (void)strutMethod:(MyStruct)aa  -> v23@0:8{?=ISC}16
NSLog(@"%s", method_getTypeEncoding(class_getInstanceMethod([self class], @selector(strutMethod:))));

那么如何理解呢?

  • v means void return type
  • 20 means the size of the argument frame (20 bytes),整个方法参数占位的总长度
  • @0 means that there is an Objective-C object type at byte offset 0 of the argument frame (this is the implicit self object in each Objective-C method),这个表示在offset为0的地方有一个objective-c的对象,在objective-c method里,首个对象是self自身。
  • :8 means that there is a selector at byte offset 8 (this is the implicit _cmd in every method, which is the selector that was used to invoke the method). 在offset为8的地方有一个SEL,由于我测试的是64位机器上,所以之前的OC的对象指针占位8个字节。
  • B16 means 在offset 16的地方,有一个bool类型的参数,由于oc的对象和sel都是指针类型,64位机下所以都是占位8位,这里的bool也就出现在offset16的地方了。至于为什么bool参数占位了4个字节。主要原因是内存对齐的原因

从上面看起来,不管是bool,uint8,uint16,int都被认为4个字节。因为他们的内存实际占位都小于4个字节,由于内存对齐原因所以实际最后占位为4字节。这里当你看最后一个MyStruct就可以看出,当主动告诉编译器取消结构体的内存对齐,就发现最后一个参数事迹展位是7(4+2+1)个字节

注:packed属性:使用该属性可以使得变量或者结构体成员使用最小的对齐方式,即对变量是一字节对齐,对域(field)是位对齐.
typedef struct  {
    uint32_t a;
    uint16_t b;
    uint8_t c;
} __attribute__((packed)) MyStruct;

未完待续

至此先了解介绍完了关于type encodings, property type encodings,method encodings。稍后继续补充了解更多的运行时编程相关的知识点,runtime programming guide~~~.

参考链接

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

推荐阅读更多精彩内容

  • 我们常常会听说 Objective-C 是一门动态语言,那么这个「动态」表现在哪呢?我想最主要的表现就是 Obje...
    Ethan_Struggle阅读 2,176评论 0 7
  • 所有的编译警告的名称:参见网址:http://fuckingclangwarnings.com注意这篇文章的创建时...
    zhangyin阅读 10,663评论 0 53
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,600评论 18 139
  • 春色初来柳鹅黄,暖阳温馨驱寒凉。 河堤之上芳草绿,野鸭游畅两三行。
    老槐树阅读 181评论 0 2
  • 第四天
    封之之阅读 168评论 0 0