IOS-runtime

标签(空格分隔): 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);
}

你可能感兴趣的:(IOS-runtime)