1.运行时简介
就是在程序运行时候的一些机制,其中主要是消息机制,oc在调用方法的时候,其实就是发送消息;而且oc在编译阶段,是不确定要调用哪个函数的,只有在运行的时候才会找对应的函数来调用
2.消息发送机制
2.1方法调用的本质就是利用runtime发送消息
获取类对象,然后去发送注册方法的消息,去调用,这只是调用没有参数的
objc_msgSend(objc_getClass("NSObject"),sel_registerName("alloc"))
消息机制的用处:1.可以装逼。2.可以用runTime调用类的私有方法
面试时候会问:方法是怎么调用的?
这时候要知道不同的方法,它存到了什么地方,对象方法存到对应的类里面,类方法存到了元类里面【meta class】(其实类也是对象,它是元类的实例对象),而元类是根元类的对象 root meta class
1.所以首先要明确去哪个类查找方法,这时候就要通过isa指针,它指向的就是你方法所在的类中(每个类都有一个方法列表,methordList,在调用发方法的时候,底层是用消息机制来实现的,这时候它会把方法编号给你传过来,可以根据方法编号,在方法列表中查出所要调用的方法,在查找的时候它也是有算法的,因为一个类中可能有很多方法,如果一个一个遍历会很耗时间,这个算法是一个哈希算法,具体怎么算的就不清楚了,反正就是加快了查找的速度)
2.在找到方法之后,其实只是找到了一个方对应的函数名,这时候要根据这个函数名去找对应的函数实现(函数名其实就相当于函数的一个入口)-------(在内存中我们是有一块区域的:方法区 就是通过方法名在这个区域找到方法实现的)
3.交换方法(如果想要在用运行时时候有提示:在Build Setting中搜索msg,设置成NO)
这个的应用场景:当自定义的一个类的方法很难维护,并且这个方法用的还很频繁,而你目前又想重构,但却不想影响当前功能,或者是想在系统的一些方法中填一些新的功能,可以使用运行时交换方法,一句话,就是交换两个方法的实现:注意如果是要在原方法中添加新的参数的话,那么是不能使用交换方法的,因为没什么意义,(但是减少参数是可以的,因为它交换时候,参数也是一一对应进行交换的)
1.创建这个类的分类:如果是系统方法,那么创建分类,如果是自定义的类,那么就直接在类里面重写load方法,
2.在分类中重写load方法,load方法是在这个类第一次调用的时候调用一次,下一次无论是子类还是本类再次调用都不会调用了,initialize这个类方是:当第一次加载这个类的时候会调用一次,但是当子类加载时候还会调用一次;
3.交换两个方法

4.动态添加方法(动态添加方法首先不需要声明)
会问到performSelector这个方法用没用过
5.万能跳转:在NSObject的分类中,写一个方法,方法需要穿入一个字典,字典中包括所跳页面的类名,和所要发的参数,同时参数的名称要和页面所接收的参数属性名称一样,然后运用运行时,便利属性名,然后给相同的属性赋值,用kvc,然后获得跟控制器,然后跳转,具体实现过程如下图,这个可以解耦合



6.动态添加属性:其实就是给一个对象添加一个关联
应用场景:
1.一般是想给系统的类添加属性方便开发,一般会在系统类的分类中,申明get和set方法,然后调用objc_setAssociate添加关联,调用objc_getAssociate获取关联,这样就可以动态的将值赋值给这个关联
2.当自己封装了一个类,已经打包SDK,同时又不想动它,但现在又得添加新的属性,那么就可以在类的分类中动态添加属性了
网友评论