标签(空格分隔): IOS-OC
[toc]
#import
相关阅读
http://yulingtianxia.com/blog/2014/11/05/objective-c-runtime/
http://www.cocoachina.com/ios/20150717/12623.html IMP详解
runtime的作用
转自: http://www.cnblogs.com/gugupluto/p/3159733.html
- 增加
增加函数:class_addMethod
增加实例变量:class_addIvar
增加属性:@dynamic标签,或者class_addMethod,因为属性其实就是由getter和setter函数组成
增加Protocol:class_addProtocol (说实话我真不知道动态增加一个protocol有什么用,-_-!!)
- 获取
获取函数列表及每个函数的信息(函数指针、函数名等等):class_getClassMethod method_getName ...
获取属性列表及每个属性的信息:class_copyPropertyList property_getName
获取类本身的信息,如类名等:class_getName class_getInstanceSize
获取变量列表及变量信息:class_copyIvarList
获取变量的值
- 替换
将实例替换成另一个类:object_setClass
将函数替换成一个函数实现:class_replaceMethod
直接通过char *格式的名称来修改变量的值,而不是通过变量
方法执行顺序
首先检查方法缓存->没有发现->检查方法列表->没有发现->resolveInstanceMethod:方法动态添加->forwardingTargetForSelector:将方法指派给其他对象调用->forwardInvocation:得到整个方法,对方法进行处理->崩溃!!!
使用
获取类的所有方法
NSString *className = NSStringFromClass([UIView class]);
const char *cClassName = [className UTF8String];
id theClass = objc_getClass(cClassName);
unsigned int outCount;
Method *m = class_copyMethodList(theClass,&outCount);
NSLog(@"%d",outCount);
for (int i = 0; i
方法操作
添加一个方法
id jx_message(id self,SEL _cmd,... ){
NSLog(@"疯了---%@",NSStringFromSelector(_cmd));
((id(*)(id, SEL,...))objc_msgSend)(self,NSSelectorFromString(@"XXX"));
return nil;
}
+(void)load{
Method init = class_getInstanceMethod(self, @selector(message));
SEL sel = NSSelectorFromString(@"XXX");
class_addMethod(self, sel, (IMP)jx_message, "v@:");
Method se = class_getInstanceMethod(self, sel);
method_exchangeImplementations(init, se);
}
交换方法
俗称的hook,这里的self是一个类类型 也就是+号方法中的self
交换类方法(+号方法)
Method orig = class_getClassMethod([self class], @selector(ssssss));
Method obj = class_getClassMethod([self class], @selector(viewDidLoad));
method_exchangeImplementations(orig, obj);
交换实例方法(-号方法)
Method orig = class_getInstanceMethod([self class], @selector(ssssss));
Method obj = class_getInstanceMethod([self class], @selector(viewDidLoad));
method_exchangeImplementations(orig, obj);
获取属性
获取实例属性列表
id objc = objc_getClass("NSObjec");
unsigned int count;//这个参数表示获取到的数组下标
objc_property_t * propertys = class_copyPropertyList(objc,&count);
从列表中获取属性名称
//ps是数组指针, *ps表示使用数组中的第1个元素
const char * name = property_getName(*ps);
获取属性的类型
const char * name = property_getAttributes(*ps);
//返回----T@"NSString",C,N
通过名称获取属性
//获取类中的属性
objc_property_t class_getProperty(Class cls, const char *name);
//获取协议中的属性
objc_property_t protocol_getProperty(Protocol *proto, const char *name, BOOL isRequiredProperty, BOOL isInstanceProperty)
获取成员变量
class_copyIvarList()
动态添加属性
static const char MJRefreshHeaderKey = '\0';
//设置
- (void)setMj_header:(MJRefreshHeader *)mj_header
{
objc_setAssociatedObject(self, &MJRefreshHeaderKey,mj_header, OBJC_ASSOCIATION_ASSIGN);
}
读取
- (MJRefreshHeader *)mj_header
{
return objc_getAssociatedObject(self, &MJRefreshHeaderKey);
}