本篇主要是Protocol、SEL相关的方法调用
完整代码在这里
#pragma mark - IBAction
- (IBAction)logRunTimeAction:(id)sender {
objc_property_attribute_t attrs[] = { { "T", "@\"NSString\"" }, { "&", "N" }, { "V", "" } };
size_t objSize = class_getInstanceSize([_person class]);
size_t allocSize = * objSize;
uintptr_t ptr = (uintptr_t)calloc(allocSize, );
// Sel
[self sel_getName:@selector(sel_getName:)];
[self sel_registerName:"runtimeTestAction3"];
[self sel_getUid:"runtimeTestAction3"];
[self sel_isEqual:@selector(runtimeTestAction3) sel2:@selector(runtimeTestAction2)];
// Protocol
[self protocol_getName:protocol];
[self protocol_getProperty:NSProtocolFromString(@"RuntimeBaseProtocol") name:"protocolString" isRequiredProperty:YES isInstanceProperty:YES];
Protocol *testProtocol = [self objc_allocateProtocol:"TestProtocol"];
[self protocol_addProperty:testProtocol name:"newProperty" attributes:attrs attributeCount: isRequiredProperty:YES isInstanceProperty:YES];
[self protocol_addProtocol:testProtocol addition:protocol];
[self protocol_addMethodDescription:testProtocol sel:@selector(runtimeTestAction3) types:"v@:" isRequiredMethod:NO isInstanceMethod:YES]; // 已注册的协议无法添加
[self objc_registerProtocol:testProtocol];
[self protocol_copyPropertyList:testProtocol];
[self protocol_copyProtocolList:testProtocol];
[self protocol_copyMethodDescriptionList:testProtocol isRequiredMethod:NO isInstanceMethod:YES];
[self protocol_isEqual:testProtocol other:protocol];
[self protocol_conformsToProtocol:testProtocol other:protocol];
}
#pragma mark - SEL
/**
* 返回指定选择器指定的方法的名称
*
* @param sel 方法选择器
*
* @return 方法选择器名称
*/
- (const char *)sel_getName:(SEL)sel {
const char *selName = sel_getName(sel);
NSLog(@"%s %s",__func__,selName);
return selName;
}
/**
* 在Objective-C Runtime系统中注册一个方法,将方法名映射到一个选择器,并返回这个选择器
*
* @param name 方法名
*
* @return 方法选择器
*/
- (SEL)sel_registerName:(const char *)name {
SEL sel = sel_registerName(name);
[_person performSelector:sel withObject:nil afterDelay:];
return sel;
}
/**
* 在Objective-C Runtime系统中注册一个方法
*
* @param name 方法名
*
* @return 方法选择器
*/
- (SEL)sel_getUid:(const char *)name {
SEL sel = sel_getUid(name);
[_person performSelector:sel withObject:nil afterDelay:];
return sel;
}
/**
* 比较两个选择器
*
* @param sel1 方法选择器1
* @param sel2 方法选择器2
*
* @return 是否匹配
*/
- (BOOL)sel_isEqual:(SEL)sel1 sel2:(SEL)sel2 {
BOOL isEqual = sel_isEqual(sel1, sel2);
if (isEqual) {
NSLog(@"%s equal",__func__);
}else{
NSLog(@"%s unequal",__func__);
}
return isEqual;
}
#pragma mark - Protocol get: 协议;属性;
/**
* 返回协议名
*
* @param protocol 协议
*
* @return 协议名
*/
- (const char *)protocol_getName:(Protocol *)protocol {
const char *name = protocol_getName(protocol);
// NSLog(@"%s %s",__func__,name);
return name;
}
/**
* 获取协议的指定属性
*
* @param protocol 协议
* @param name 属性名
* @param isRequiredProperty 是否为必须属性
* @param isInstanceProperty 是否为实例属性
*
* @return 属性
*/
- (objc_property_t)protocol_getProperty:(Protocol *)protocol name:(const char *)name isRequiredProperty:(BOOL)isRequiredProperty isInstanceProperty:(BOOL)isInstanceProperty{
objc_property_t property = protocol_getProperty(protocol, name, isRequiredProperty, isInstanceProperty);
NSLog(@"%s %s",__func__,property_getName(property));
return property;
}
#pragma mark - Protocol add:属性;方法;协议;
/**
* 为协议添加属性(只能向未注册的协议中添加)
*
* @param protocol 协议
* @param name 属性名
* @param attributes 属性类型字符串
* @param attributeCount 属性类型数量
* @param isRequiredProperty 是否为必需属性
* @param isInstanceProperty 是否为实例属性
*/
- (void)protocol_addProperty:(Protocol *)protocol name:(const char *)name attributes:(const objc_property_attribute_t *)attributes attributeCount:(unsigned int)attributeCount isRequiredProperty:(BOOL)isRequiredProperty isInstanceProperty:(BOOL)isInstanceProperty {
protocol_addProperty(protocol, name, attributes, attributeCount, isRequiredProperty, isInstanceProperty);
}
/**
* 为协议添加方法(只能向未注册的协议中添加)
*
* @param protocol 协议
* @param sel 方法选择器
* @param types 方法类型
* @param isRequiredMethod 是否为必需方法
* @param isInstanceMethod 是否为实例方法
*/
- (void)protocol_addMethodDescription:(Protocol *)protocol sel:(SEL)sel types:(const char *)types isRequiredMethod:(BOOL)isRequiredMethod isInstanceMethod:(BOOL)isInstanceMethod{
protocol_addMethodDescription(protocol, sel, types, isRequiredMethod, isInstanceMethod);
}
/**
* 添加一个已注册的协议到一个未注册的协议中(只能向未注册的协议中添加)
*
* @param protocol 协议
* @param addition 被添加的已注册的协议
*/
- (void)protocol_addProtocol:(Protocol*)protocol addition:(Protocol*)addition {
protocol_addProtocol(protocol, addition);
}
#pragma mark - Protocol copy:协议列表;属性列表
/**
* 获取协议中的属性列表
*
* @param protocol 协议
*
* @return 属性
*/
- (objc_property_t *)protocol_copyPropertyList:(Protocol *)protocol {
unsigned int outCount;
objc_property_t *propertyList = protocol_copyPropertyList(protocol,&outCount);
for (int i = ; i < outCount; i++) {
objc_property_t property = propertyList[i];
NSLog(@"%s %s",__func__,property_getName(property));
}
return propertyList;
}
/**
* 获取协议中遵循的协议列表
*
* @param protocol 协议
*
* @return 协议列表
*/
- (Protocol **)protocol_copyProtocolList:(Protocol *)protocol {
unsigned int outCount;
Protocol **protocolList = protocol_copyProtocolList(protocol,&outCount);
for (int i = ; i < outCount; i++) {
Protocol *protocol = protocolList[i];
NSLog(@"%s %s",__func__,protocol_getName(protocol));
}
return protocolList;
}
/**
* 获取协议的方法列表
*
* @param protocol 协议
* @param isRequiredMethod 是否为必需方法
* @param isInstanceMethod 是否为实例方法
*
* @return 方法列表
*/
- (struct objc_method_description *)protocol_copyMethodDescriptionList:(Protocol *)protocol isRequiredMethod:(BOOL)isRequiredMethod isInstanceMethod:(BOOL)isInstanceMethod{
unsigned int outCount;
struct objc_method_description *methodList = protocol_copyMethodDescriptionList(protocol, isRequiredMethod, isInstanceMethod, &outCount);
for (int i = ; i < outCount; i++) {
struct objc_method_description method = methodList[i];
NSLog(@"%s %@",__func__,NSStringFromSelector(method.name));
}
return methodList;
}
#pragma mark - Protocol 判断
/**
* 测试两个协议是否相等
*
* @param protocol 协议
* @param other 另外一个协议
*
* @return 是否相等
*/
- (BOOL)protocol_isEqual:(Protocol *)protocol other:(Protocol *)other {
BOOL isEqual = protocol_isEqual(protocol, other);
if (isEqual) {
NSLog(@"%s %s equal %s ",__func__,protocol_getName(protocol),protocol_getName(other));
}else{
NSLog(@"%s %s unequal %s ",__func__,protocol_getName(protocol),protocol_getName(other));
}
return isEqual;
}
/**
* 查看协议是否遵循了另一个协议
*
* @param protocol 协议
* @param other 另外一个协议
*
* @return 是否遵循
*/
- (BOOL)protocol_conformsToProtocol:(Protocol *)protocol other:(Protocol *)other {
BOOL isConform = protocol_conformsToProtocol(protocol, other);
if (isConform) {
NSLog(@"%s %s conform %s ",__func__,protocol_getName(protocol),protocol_getName(other));
}else{
NSLog(@"%s %s unconform %s ",__func__,protocol_getName(protocol),protocol_getName(other));
}
return isConform;
}