Objective-C Runtime机制

关于runtime 网上有很多文章了,他的原理,以及调用。关于相关函数名解释在这里,我也就不一一列举了。直接干货走起

#import <objc/runtime.h>
#import <objc/message.h>
#pragma mark - 利用rutime动态修改其他类内部变量方法
- (void)exchangeClassVar
{
    TKTest *t = [[TKTest alloc] init];
    // 先定义一个数量
    unsigned int count = 0;
    // 获得该class的变量个数
    Ivar *test = class_copyIvarList([TKTest class], &count);
    for (int i = 0; i<count; i++) {
        Ivar var = test[i];
        // 将IVar变量转化为字符串
        const char *a = ivar_getName(var);
        // 获取IVar的类型
        const char *b = ivar_getTypeEncoding(var);
        // 取一个临时变量 char无法直接作比较
        NSString *exa = [NSString stringWithFormat:@"%s",a];
        if ([exa isEqualToString:@"_name"]) {
            // 在此改变内部name变量的属性
            object_setIvar(t, var, @"chengong");
        }
        NSLog(@"%s----%s",a,b);
    }
    NSLog(@"%@",[t description]);
}
#pragma mark - 利用rutime动态修改其他类内部私有函数
//具体的实现,即IMP所指向的方法
int myAddingFunction(id self, SEL _cmd, NSString *str, NSString *str1)
{
    NSLog(@"I am added funciton%@---%@",str,str1);
    return 10;
}
- (void)exchangeClassMethod
{
/*
i:返回值类型int,若是v则表示void
@:参数id(self)
::SEL(_cmd)
@:id(str)
*/
    class_addMethod([TKTest class], @selector(method::), (IMP)myAddingFunction, "i@:@@");
    TKTest *t = [[TKTest alloc] init];
    // 先定义一个数量
    unsigned int count = 0;
    // 获得该class的私有函数个数
    Method *m = class_copyMethodList([TKTest class], &count);
    for (int i = 0; i<count; i++) {
        SEL name = method_getName(m[i]);
        // 方法名
        NSString *methodName = [NSString stringWithCString:sel_getName(name) encoding:NSUTF8StringEncoding];
//      NSLog(@"%@",methodName);
}
    //尝试调用新增的方法
    [t performSelector:@selector(method::) withObject:@"haha" withObject:@"ooooo"];
}
#pragma mark - 方法之间的互换
- (void)exchangeMethod
{
    Method method1 = class_getInstanceMethod([NSString class], @selector(lowercaseString));
    Method method2 = class_getInstanceMethod([NSString class], @selector(uppercaseString));
    method_exchangeImplementations(method1, method2);
    NSLog(@"lowcase :%@", [@"CE shi" lowercaseString]);
    NSLog(@"uppercase :%@", [@"CE shi" uppercaseString]);
}
#pragma mark - 动态添加一个属性
- (void)setTest:(TKTest *)test
{
    objc_setAssociatedObject(self, &addTestKey, test, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (TKTest *)test
{
    return objc_getAssociatedObject(self, &addTestKey);
}