欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

ios开发Runtime的简单使用方法

程序员文章站 2022-06-16 12:28:12
ios开发Runtime的简单使用方法,其实在OC底层本质上就是C语言函数的调用,去动态的发送消息。下面就拿一个alloc init的方法来举个例子,我们完全可以去调用运行时的函数...

ios开发Runtime的简单使用方法,其实在OC底层本质上就是C语言函数的调用,去动态的发送消息。下面就拿一个alloc init的方法来举个例子,我们完全可以去调用运行时的函数,这样就可以去创建一个对象了。

   Person * p = objc_msgSend(objc_getClass("Person"),sel_registerName("alloc"));
 
  objc_msgSend(p, sel_registerName("init"));
其实我们在终端也可以去输入下面的命令,就可以去查看OC的C语言的实现,就会发现其实创建对象就和上面的运行时代码是很像的
clang -rewrite-objc main.m
在这里也需要了解两个概念性的问题就是SEL和IMP,其实SEL就是方法的编号,而IMP就是需要去执行方法的指针,我们可以通过方法的编号去找到这个代码的具体实现。

我们在下面可以进行交换两个对象的方法,其中Method就是指向struct objc_method的指针。其实SEL和IMP就相当于是一本书里面的标题和页码,我们可以通过标题知道页码,当然也可以去根据页码知道具体的内容。

    Method method1 = class_getInstanceMethod([self class], @selector(eat));
    Method method2 = class_getInstanceMethod([self class], @selector(sleep));
    //进行方法交换
    method_exchangeImplementations(method1, method2);

有两个方法是我们需要知道的一个就是当我们没有实现某个我们调用的类方法的时候回来到下面的这个函数
+(BOOL)resolveClassMethod:(SEL)sel

另外一个就是在我们实现我们调用的对象方法的时候如果没找到会调用下面的这个函数
+(BOOL)resolveInstanceMethod:(SEL)sel
如果我们想要在运行时动态的添加函数就可以在这里面进行添加,并且下面需要注意的是如果我们要写的函数要带有参数的话,那么函数的前面就要带有两个参数,一个是self,还有一个就是SEL _cmd,当前_cmd你可以改名字。self其实就是方法的调用者,而SEL其实就是方法的编号
+(BOOL)resolveInstanceMethod:(SEL)sel
{
    
    //动态的添加方法
    /*方法的参数一:是这个类
     参数二:方法
     参数三 函数指针
     参数四 就是返回值的类型加参数
     */
    
    class_addMethod(self, sel,hello,"");
    
    return [super resolveInstanceMethod:sel];
}
void hello(id self,SEL _cmd,NSString *str1,NSString * str2)
{
    NSLog(@"%@------%@",str1,str2);
    NSLog(@"hello world");
}
还有一个需要注意的是死循环可能不会导致程序直接崩溃,但是如果是函数的递归调用就肯定会导致程序的崩溃的,因为函数执行的时候有自己的临时栈,所以会导致堆栈溢出了,导致程序崩溃。