协议(Protocol)的定义
协议主要是用来规范一些接口的,使遵循该协议的对象都能遵循某些接口。
Protocol
在runtime中定义如下:
struct protocol_t : objc_object{
const char *mangledName;
struct protocol_list_t *protocols; // 该协议遵循的协议列表
method_list_t *instanceMethods; // 实例方法
method_list_t *classMethods; // 类方法
method_list_t *optionalInstanceMethods; // 可选择实现的实例方法
method_list_t *optionalClassMethods; // 可选择实现的类方法
property_list_t *instanceProperties; // 实例属性
uint32_t size;
uint32_t flags;
const char **_txtendedMethodTypes;
const char *_demangledname;
property_list_t *_classProperties; // 类属性
}
协议中主要存储有一系列方法,包括@required
和@optional
的,还有属性property
。协议与Method
初始化过程类似,都是在编译期便确定下来了。
协议(Protocol)的生成
首先我们先定义一个协议,并让一个类遵循该协议。
@protocol TestProtocol<NSObject>
@optional
- (void)testProtocolMethod;
@property(nonatomic) NSString *testStr;
@end
@interface TestProtocolClass : NSObject<TestProtocol>
@end
接下来我们用clang
命令重写该文件。
1.遵循的协议
static struct /*_protocol_list_t*/ {
long protocol_count; // Note, this is 32/64 bit
struct _protocol_t *super_protocols[1];
} _OBJC_PROTOCOL_REFS_TestProtocol __attribute__ ((used, section ("__DATA,__objc_const"))) = {
1,
&_OBJC_PROTOCOL_NSObject
};
_OBJC_PROTOCOL_NSObject
其实就是协议NSObject
。
2.方法列表
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_TestProtocol __attribute__ ((used, section ("__DATA,__objc_const"))) = {
sizeof(_objc_method),
3,
{{(struct objc_selector *)"testProtocolMethod", "v16@0:8", 0},
{(struct objc_selector *)"testStr", "@16@0:8", 0},
{(struct objc_selector *)"setTestStr:", "v24@0:8@16", 0}}
};
协议TestProtocol
共有三个方法,其中包含属性testStr
的setter
和getter
。
3.属性
static struct /*_prop_list_t*/ {
unsigned int entsize; // sizeof(struct _prop_t)
unsigned int count_of_properties;
struct _prop_t prop_list[1];
} _OBJC_PROTOCOL_PROPERTIES_TestProtocol __attribute__ ((used, section ("__DATA,__objc_const"))) = {
sizeof(_prop_t),
1,
{{"testStr","T@\"NSString\",N"}}
};
4. 协议的初始化
struct _protocol_t _OBJC_PROTOCOL_TestProtocol __attribute__ ((used)) = {
0,
"TestProtocol",
(const struct _protocol_list_t *)&_OBJC_PROTOCOL_REFS_TestProtocol,
0,
0,
(const struct method_list_t *)&_OBJC_PROTOCOL_OPT_INSTANCE_METHODS_TestProtocol,
0,
(const struct _prop_list_t *)&_OBJC_PROTOCOL_PROPERTIES_TestProtocol,
sizeof(_protocol_t),
0,
(const char **)&_OBJC_PROTOCOL_METHOD_TYPES_TestProtocol
};
struct _protocol_t *_OBJC_LABEL_PROTOCOL_$_TestProtocol = &_OBJC_PROTOCOL_TestProtocol;
最终将该协议遵循的协议、实现的方法和属性初始化为结构体protocol_t
。
协议中的属性与类中的属性
协议和类一样,也可以声明属性@property
,不同的是,协议中的属性property=setter+getter
,没有类中的变量ivar
,协议中使用属性的目的就是希望遵守该协议的对象能够实现该属性。
小结:
- 协议主要是用来规范一些接口的,使遵循该协议的对象都能遵循某些接口。
- 协议和方法类似,也是在编译期便确定下来的。
- 协议中也能声明属性,但只会生成
setter
和getter
。
网友评论