iOS下RunTime分析二(协议C++源码)
接上一篇文章:iOS下RunTime分析一(OC文件编译为C++)
这里主要是解释iOS下RunTime分析一(OC文件编译为C++)中的第5点疑问。
先看协议部分的OC源码
头文件:
@protocol ChildDelegate <NSObject>
@optional
- (void)optionalMethod;
@property (nonatomic, strong) NSObject *optionalObj;
@required
- (void)requiredMethod:(NSString *)obj;
@property (nonatomic, strong) NSObject *requiredObj;
@end
@interface ChildObject : MyObject
<NSCopying, ChildDelegate>
@end
源文件:
@interface ChildObject ()
{
int childA;
NSObject *childObj;
}
@property (nonatomic, strong) NSString *childName;
@end
@implementation ChildObject
@synthesize requiredObj = _requiredObj;
+ (void)showChildClassMethod
{
NSLog(@"child object");
}
- (void)childInstanceMethod
{
NSLog(@"child instance object");
}
- (id)copyWithZone:(NSZone *)zone
{
return nil;
}
- (void)optionalMethod
{
}
- (void)requiredMethod:(NSString *)obj
{
}
@end
现在来看下编译成C++之后的源代码,与RunTime分析一相似的部分,不在重新写了。
会生成一个protocol的结构体:
struct _protocol_t {
void * isa; // NULL
const char *protocol_name;
const struct _protocol_list_t * protocol_list; // super protocols
const struct method_list_t *instance_methods;
const struct method_list_t *class_methods;
const struct method_list_t *optionalInstanceMethods;
const struct method_list_t *optionalClassMethods;
const struct _prop_list_t * properties;
const unsigned int size; // sizeof(struct _protocol_t)
const unsigned int flags; // = 0
const char ** extendedMethodTypes;
};
以及与protocol相关的一些全局静态变量:
(used, section ("__DATA,__objc_const"))
static const char *_OBJC_PROTOCOL_METHOD_TYPES_NSCopying [] =
{
"@24@0:8^{_NSZone=}16"
};
(used, section ("__DATA,__objc_const"))
static struct /*_method_list_t*/ {
unsigned int entsize; // sizeof(struct _objc_method)
unsigned int method_count;
struct _objc_method method_list[1];
} _OBJC_PROTOCOL_INSTANCE_METHODS_NSCopying = {
sizeof(_objc_method),
1,
{ {(struct objc_selector *)"copyWithZone:", "@24@0:8^{_NSZone=}16", 0} }
};
struct _protocol_t _OBJC_PROTOCOL_NSCopying = {
0,
"NSCopying",
0,
(const struct method_list_t *)&_OBJC_PROTOCOL_INSTANCE_METHODS_NSCopying,
0,
0,
0,
0,
sizeof(_protocol_t),
0,
(const char **)&_OBJC_PROTOCOL_METHOD_TYPES_NSCopying
};
struct _protocol_t *_OBJC_LABEL_PROTOCOL_$_NSCopying = &_OBJC_PROTOCOL_NSCopying;
以上是NSCopying的协议的生成代码。
下面来继续看ChildDelegate协议的生成代码:
(used, section ("__DATA,__objc_const"))
static const char *_OBJC_PROTOCOL_METHOD_TYPES_ChildDelegate =
{
"v24@0:8@\"NSString\"16",
"@\"NSObject\"16@0:8",
"v24@0:8@\"NSObject\"16",
"v16@0:8",
"@\"NSObject\"16@0:8",
"v24@0:8@\"NSObject\"16"
};
//因为ChildDelegate是继承自NSObojce协议的,所以会多出来这个结构体
(used, section ("__DATA,__objc_const"))
static struct /*_protocol_list_t*/ {
long protocol_count; // Note, this is 32/64 bit
struct _protocol_t *super_protocols[1];
} _OBJC_PROTOCOL_REFS_ChildDelegate = {
1,
&_OBJC_PROTOCOL_NSObject
};
//@required 方法
(used, section ("__DATA,__objc_const"))
static struct /*_method_list_t*/ {
unsigned int entsize; // sizeof(struct _objc_method)
unsigned int method_count;
struct _objc_method method_list[3];
} _OBJC_PROTOCOL_INSTANCE_METHODS_ChildDelegate = {
sizeof(_objc_method),
3,
{ {(struct objc_selector *)"requiredMethod:", "v24@0:8@16", 0},
{(struct objc_selector *)"requiredObj", "@16@0:8", 0},
{(struct objc_selector *)"setRequiredObj:", "v24@0:8@16", 0} }
};
//optional 方法
(used, section ("__DATA,__objc_const"))
static struct /*_method_list_t*/ {
unsigned int entsize; // sizeof(struct _objc_method)
unsigned int method_count;
struct _objc_method method_list[3];
} _OBJC_PROTOCOL_OPT_INSTANCE_METHODS_ChildDelegate = {
sizeof(_objc_method),
3,
{ {(struct objc_selector *)"optionalMethod", "v16@0:8", 0},
{(struct objc_selector *)"optionalObj", "@16@0:8", 0},
{(struct objc_selector *)"setOptionalObj:", "v24@0:8@16", 0} }
};
//property
(used, section ("__DATA,__objc_const"))
static struct /*_prop_list_t*/ {
unsigned int entsize; // sizeof(struct _prop_t)
unsigned int count_of_properties;
struct _prop_t prop_list[2];
} _OBJC_PROTOCOL_PROPERTIES_ChildDelegate = {
sizeof(_prop_t),
2,
{ {"optionalObj","T@\"NSObject\",&,N"},
{"requiredObj","T@\"NSObject\",&,N"} }
};
struct _protocol_t _OBJC_PROTOCOL_ChildDelegate = {
0,
"ChildDelegate",
&_OBJC_PROTOCOL_REFS_ChildDelegate,
&_OBJC_PROTOCOL_INSTANCE_METHODS_ChildDelegate,
0,
)&_OBJC_PROTOCOL_OPT_INSTANCE_METHODS_ChildDelegate,
0,
&_OBJC_PROTOCOL_PROPERTIES_ChildDelegate,
sizeof(_protocol_t),
0,
&_OBJC_PROTOCOL_METHOD_TYPES_ChildDelegate
};
struct _protocol_t *_OBJC_LABEL_PROTOCOL_$_ChildDelegate = &_OBJC_PROTOCOL_ChildDelegate;
……
以此类推如何还实现了其他的协议,那么又会生成一个_protocol_t结构体的对象。
生成的一系列_protocol_t这个结构体对象,最终会被组织成一个_protocol_list_t类型的结构体对象,如下:
(used, section ("__DATA,__objc_const"))
static struct /*_protocol_list_t*/ {
long protocol_count; // Note, this is 32/64 bit
struct _protocol_t *super_protocols[2];
} _OBJC_CLASS_PROTOCOLS_$_ChildObject = {
2,
{&_OBJC_PROTOCOL_NSCopying,
&_OBJC_PROTOCOL_ChildDelegate}
};
生成的_OBJC_CLASS_PROTOCOLS_$_ChildObject会被加到RO_ChildObject中去。
(used, section ("__DATA,__objc_const"))
static struct _class_ro_t RO_ChildObject = {
0, __OFFSETOFIVAR__(struct ChildObject, childA),
sizeof(struct ChildObject_IMPL),
(unsigned int)0,
0,
"ChildObject",
&_OBJC_$_INSTANCE_METHODS_ChildObject,
&_OBJC_CLASS_PROTOCOLS_$_ChildObject,
&_OBJC_$_INSTANCE_VARIABLES_ChildObject,
0,
0,
};
总结:
一个OC对象类实现了n个协议就会生成对应的n个_protocol_t的结构体对象,而这些对象最终会被放到一个_protocol_list_t结构体中赋值给该类对象的一个变量中。