iOS高级开发 RunTime机制讲解一

作者: kevinLY | 来源:发表于2016-03-23 14:20 被阅读358次

    还是直接上代码,来的实在
    下载demo:https://github.com/sleepsheep/RunTimeDemo01
    先做下准备工作:
    1、新建一个OC的项目,这个就不用多说了哈
    2、新建两个类:CustomClass 和 CustomClassOther

    @interface CustomClass : NSObject
    - (void)testFun1;
    @end
    @implementation CustomClass
    - (void)testFun1 {
    NSLog(@"testFun1");
    }
    @end
    
    @interface CustomClassOther : NSObject
    - (void)testFun2;
    @end
    @implementation CustomClassOther
    - (void)testFun2 {
    NSLog(@"testFun2");
    }
    @end
    

    3、新建一个测试类:TestClass
    下面进入正题:
    方法讲解

    1、对象copy: id object_copy(id obj, size_t size)----实现了对对象的拷贝
    参数说明:1、id obj : 想要拷贝的对象 2、size_t : 申请拷贝后的对象的空间大小
    返回值:id : 返回obj对象的拷贝
    2、对象的释放 object_dispose(id obj)
    参数说明:1、id obj : 你想要释放的对象
    3、获取对象的类 class object_getClass(id obj)
    参数说明:1、id obj : 类的对象
    返回值:返回对象obj的类
    4、更改对象的类 id object_setClass(id obj, otherClass)
    参数说明:1、id obj : 一个类的对象 2、OtherClass : 另外一个类
    返回值:返回另外一个类 OtherClass的实例
    备注:返回值将拥有类OtherClass的方法
    5、获取对象的类名 const char object_getClassName(id obj)
    参数说明:1、id obj : 一个类的对象
    返回值:const char : 返回对象obj的类的名称
    6、给类添加方法:
    BOOL class_addMethod(Class cls, SEL name, IMP imp, const char *types)
    参数说明:1、Class cls : 被添加方法的类 2、SEL name : 方法名字 3、IMP imp : 实现这个方法的函数 4、types : 一个定义该函数返回值类型和参数类型的字符串
    class_addMethod([TestClass class], @selector(ocMethod:), (IMP)cfunction, "i@:@");
    其中 types 为 "i@:@" 分别表示:
    i:返回值类型为int, 若是v 则表示void
    @:参数id(self)
    : :SEL(_cmd)
    @:id(str)

    代码:

    #import "TestClass.h"
    #import <objc/runtime.h>
    #import "CustomClass.h"
    #import "CustomClassOther.h"
    @implementation TestClass
    //1、对象的拷贝
    - (void)copyObj {   
    CustomClass *obj = [CustomClass new];   
    NSLog(@"%p", &obj);//0x7fff5fbff7c8       
    //object_copy 的两个参数:1、已经存在的对象本身  2、需要申请的对象的空间大小  
    id objTest = object_copy(obj, sizeof(obj));   
    NSLog(@"%p", &objTest);//0x7fff5fbff7c0   
    NSLog(@"%@", objTest);//[objTest testFun1];//testFun1
    }
    //2、对象的释放
    - (void)objectDispose {
    CustomClass *obj = [CustomClass new];
    object_dispose(obj);//
    [obj release];//*** error for object 0x100500510: pointer being freed was not allocated *** set a breakpoint in malloc_error_break to debug
    [obj testFun1];
    }
    //3、返回一个类Class
    - (void)getClassTest {
    CustomClass *obj = [CustomClass new];
    NSLog(@"%p", &obj);//0x7fff5fbff7c8
    id objTest = object_getClass(obj);
    NSLog(@"%@", NSStringFromClass(objTest));//CustomClass
    }
    //4、更改对象的类
    - (void)setClassTest {
    CustomClass *obj = [CustomClass new];
    [obj testFun1];//testFun1
    Class aClass = object_setClass(obj, [CustomClassOther class]);
    NSLog(@"aClass:%@", NSStringFromClass(aClass));//aClass:CustomClass
    NSLog(@"objClass:%@", NSStringFromClass([obj class]));//objClass:CustomClassOther
    [obj testFun2];//testFun2
    if ([obj respondsToSelector:@selector(testFun2)]) {
    [obj performSelector:@selector(testFun2) withObject:nil];//testFun2
    }
    }
    //5、获取对象的类的名称
    - (void)getClassNameTest {
    CustomClass *obj = [CustomClass new];
    NSString *objName = [NSString stringWithCString:object_getClassName(obj) encoding:NSUTF8StringEncoding];
    NSLog(@"%@", objName);//CustomClass
    }
    //6、给一个类添加方法
    //一个参数
    - (void)oneParam {
        TestClass *testClass = [[TestClass alloc] init];
        //添加方法
        class_addMethod([TestClass class], @selector(ocMethod:), (IMP)cfunction, "i@:@");
        if ([testClass respondsToSelector:@selector(ocMethod:)]) {
            NSLog(@"YES");//YES
        } else {
            NSLog(@"sorry");
        }
        
        int a = (int)[testClass ocMethod:@"我是一个OC的method,C函数的实现"];//我是一个OC的method,C函数的实现
        NSLog(@"a=%d", a);//10
    }
    
    - (void)twoParam {
        TestClass *testClass = [[TestClass alloc] init];
        //添加方法
        class_addMethod([TestClass class], @selector(ocMethod2:), (IMP)cfunction2, "i@:@@");
        
        if ([testClass respondsToSelector:@selector(ocMethod2:)]) {
            NSLog(@"YES");//YES
        } else {
            NSLog(@"NO");
        }
    
        int a = (int)[testClass ocMethod2:@"我是第一个参数", @"我是第二个参数"];//str = 我是第一个参数, str1 = 我是第二个参数
        NSLog(@"%d", a);//10
    }
    
    #pragma mark --help
    //一个参数
    int cfunction(id self, SEL _cmd, NSString *str) {
        NSLog(@"%@", str);
        return 10;
    }
    
    //一个参数
    int cfunction2(id self, SEL _cmd, NSString *str, NSString *str1) {
        NSLog(@"str = %@, str1 = %@", str, str1);
        return 10;
    }
    
    @end
    

    相关文章

      网友评论

      • 喵小帅:id objTest = object_copy(obj, sizeof(obj));关于这一句,问下问什么我找不到object_copy这个方法?
        kevinLY:@喵小帅 你好,这个因为没有涉及到界面,所以我创建的是Command line tool ,是OC写的,我不明白你说的找不到object_copy方法?这个方法在runtime.h文件里面,你可以用快捷键 Command + shift + o , 搜一下runtime.h !
        喵小帅:@sunwindyLy ARC那个我知道的,我是没找到object_copy方法看了下demo,这个好像是C语言写的?
        kevinLY:@喵小帅 你需要把ARC参数设成NO :smiley:

      本文标题:iOS高级开发 RunTime机制讲解一

      本文链接:https://www.haomeiwen.com/subject/klgllttx.html