1.什么是runtime?
oc是一门动态语言,所谓动态语言就是在编译阶段无法确定调用的函数以及属性的类型,只有在运行阶段首次确定类型和调用的函数。
runtime就是动态语言下核心的一个库,底层都会通过obj_sendMsg来处理消息转发机制。也是因为拥有runtime使得oc语言灵活性
比较强,能够具有动态、动态绑定、动态解析的特性。
2.runtime中的obj_calss和obj_object结构体中有什么 ?
2.1 obj_object归属类的id和归属类的指针
2.2 obj_calss 有method_list、objc_ivar_list、objc_protocol_list、objc_cach、isa、objc_cache、name等
3.runtime方法调用流程?
1、当调用个对象的时候,会通过obj_oject的isa指针找对对应的归属类。
2、从归属类(obj_class)类中的obj_cache中寻找对应的相等的sel方法编号。
3、如果没有找到,继续obj_class中的obj_method_lish中查找,如果找到写入obj_cache中。
4、如果没有到找到,会一直找到它的元类上。
5、如果元类也没有的话,会调用消息动态解析方法(resovleInstace和resloveClass)的方法,查看是否存在绑定的方法。
6、如果没有绑定方法,会调用消息转发方法(forwardingTagert)的方法。查看是否存在转发对象。
7、如果没有存在消息转发对象,会调用(methodSinature)的方法,查看是否有方法签名返回类型和参数类型。
8、如果不存在签名方法和类型,就会崩溃,找不到方法。
9、存在签名的方法,就是继续执行forwardingInvocation方法,最后一次通知绑定对象寻找IMP地址。
10、如果在forwardingInvocation没有找到IMP,就会调用找不到方法。
4.runtime的方法交换使用场景 ?
1、可以修改系统原有的方法交换自定义的方法。
2、实现统计页面调用的次数。
3、按钮重复性点击的事件。
4、表的异常处理占位图。
5、归档和解档
5.runtime的方法交换的流程 ?
1、方法交换要放在+(viod)load中处理。
2、在load中首先使用class_addMehod的方法添加新方法。
3、添加成功后,使用class_replaceMethod替换原来的方法。
4、如果添加失败的话,则说明已经有添加成功。直接使用class_exchangeMethod的方法替换。
5、在交换方法时候,使用dispach_One的方法。
6、在新方法中调用新方法。
使用注意要点:
1、使用load时候,切记不要做初始化和大开销大内存逻辑。因为程序顺序是,父类->当前类->分类->mian
2、使用的时候要在load方法,不是在init方法中,因为init是在load前调用的。
3、使用的时候如果方法相同是不会覆盖原来的方法,会放在置顶,所以一般不会调用到原来的方法。
4、在新方法中调用新方法。
6. rutime的catagroy以及和Extendtion的区别?
catagroy是动态性的,在不改变原有类的内存结构下,增加自己的方法和属性。
Extendstion是静态的。也就是在编译阶段就要确定方法和类型了。而且Extendtion只是拓展一些方法,具体的实现还是在本类的.m中
去实现,如果对系统的类增加方法和增加属性书没有办法的。
他们的作用都是相似的
1、对类功能进行文件分类,阅读性更加高。
2、对原有类进行增加方法和属性。
3、可以模拟多继承的方法。
4、缩减代码体积盘大问题。
7. catagroy如何添加属性,如果碰到weak的属性如何修饰?
1、在分类说明一个属性,然后重get和set的方法。
2、重写set方法使用objc_setAssociatedObject
3、get方法使用objec_getAssociatedObject
备注:如果在使用weak修饰属性的时候,默认runtime是没有weak修饰,可以用到assign,但是weak不会造成引用计数增加
而且在对象被释放后会把指针指向nil,如果用到assign!对象被释放的时候,指针依然会被指向原来的位置,再次掉会存在野
指针的情况,所以需要用在包裹一层,就是在set和set方法创建一个当前分类对象,用当前分类对象去value
8. id、NSObject、instace的区别:
id和NSObject都是万能指针,id可以指向任意类型的对象,不包含基本数据类型。NSObject可以指向任何继承于NSObject的对象。
id是动态指针,NSObject是静态指针,id只有在运行时候才知道对象,NSObject需要做强制转化。
instace只可以用来做返回值类型的,而且得到类型的时候更加精确。
9.weak和assignd的区别,什么场景下使用,代理为什么使用weak ?
weak是弱指针, 在对象被销毁的时候会把weak修饰的属性置为空,避免造成野指针,只能修饰对象类型。
assign对象被释放的时候不会指向nil,对象被释放了还是指向原来的地址。调用的话容易产生野指针。
assign可以修对象和基本数据类型。
代理要使用weak,weak可以说是非持有关系,对象释放了就指向nil,什么时候释放是由外部来控制,可以用assign但是用assign的时需要
对象被释放的时候,把delegate指向nil。
10.什么情况下使用copy来修饰?
copy一般出现在存在可变和不可以的双向时候使用的,比如dict和NSMutableDict、数组和字符串。
用copy修饰是因为担心在非必要的地方修改了,导致不是原有的值,所以使用copy将其拷贝一份,而不受影响。
11.nonatomic和atomic的区别?
如果在声明一个属性的时候,没确定原子还是非原子的话,默认会使用atomic,2者区别在于一个会在get和set的方法中增加线程安全。保证获得属性的
完整性,但是仅限于get和set一次完整,如果涉及到多线程还是得我们自己去实现。同时atomic的效率比较低,一般开发也是用nonatomic。
12.对property进行说明,已经它的参数进行说明?
1、get和set的申明
2、get和set的实现
3、成员变量
参数说明
原子:nonatomic 和 atomic
读写:readWirte 和 radOnly
修饰:assign copy strong weak
方法名:geter和seter
13.new和[alloc init]的有什么区别,代表什么意思?
1、开辟内存空间
2、初始化对象
3、返回指针首地址
区别:alloc init会申请完内存空间后,会调用内部的zone的一个方法,然后把相邻指针的放在同个位置,这样调用起来更快。
14.+(viod) load的调用顺序?
1、调用父类
2、调用本类
3、调用分类
4、调用mian入口
注意:使用load的时候切记不要在这里初始化和大开销大逻辑。不然main入口不知道什么时候才能进去
网友评论