[iOS]复习笔记

runtime机制

objective-c代码总是先预编译成C代码,runtime机制也是基于C的实现。
消息机制是runtime的基础。研究runtime机制基本上就是阅读和理解对应的C代码。

  • objc_msgSend(C代码)

    void objc_msgSend(id self,SEL op, ...)
    
    objc_msgSend(self,@selector(doSomethingWithVar:),var1);
    
  • 消息转发机制

  • clang -rewrite-objc xxx.mm

  • + (BOOL) resolveInstanceMethod:(SEL)aSEL

  • – (id)forwardingTargetForSelector:(SEL)aSelector

  • – (void)forwardInvocation:(NSInvocation *)anInvocation

  • doesNotRecognizeSelector

  • 方法对换

    void method_exchangeImplementations(Method m1, Method m2) 
    

NSArray用strong修饰有什么问题?

如果不小心将一个可变数组赋值给它,将导致修改可变数组的元素的时候导致该“不可变数组”的元素发生变化。实际上指向了可变数组的内存。

NSMutableArray用copy修饰有什么问题?

初始化的时候会导致得到一个不可变数组,增加修改的时候会崩溃。doesnotreconginizeselector

循环引用

  • weak解除循环引用
  • block中的self并不是总是引起循环引用
    如果只是block引用了self,self并不持有block,并不会引起循环引用问题。

Block

  • 是一个NSObject对象
  • ARC下默认copy到堆上

category使用和实现机制

  • 实现原理

利用runtime动态修改 methodList 的值来添加成员方法,这也是 Category 实现的原理,因此它不能增加成员变量。添加数据可以通过关联对象来绑定一个对象。

  • 使用场景

    • 为已有的类增加方法
    • 可以把类的实现分开在几个不同的文件里面。
      a) 可以减少单个文件的体积
      b) 可以把不同的功能组织到不同的category里
      c) 可以由多个开发者共同完成一个类
      d) 可以按需加载想要的category
    • 声明私有方法
    • 模拟多继承
    • 把framework的私有方法公开
  • extension和category的区别?

  • extension

extension在编译期决议,它就是类的一部分,在编译期和头文件里的@interface以及实现文件里的@implement一起形成一个完整的类,它伴随类的产生而产生,亦随之一起消亡。extension一般用来隐藏类的私有信息,你必须有一个类的源码才能为一个类添加extension,所以你无法为系统的类比如NSString添加extension。
extension可以添加实例变量.

  • category

category是在运行期决议的。
category是无法添加实例变量的(因为在运行期,对象的内存布局已经确定,如果添加实例变量就会破坏类的内部布局,这对编译型语言来说是灾难性的)。但是通过关联对象可以绑定数据成员。

typedef struct category_t {
   
    const char *name;
    classref_t cls;
    struct method_list_t *instanceMethods;
    struct method_list_t *classMethods;
    struct protocol_list_t *protocols;
    struct property_list_t *instanceProperties;
} category_t;

上面结构表面,category可以增加实例方法,类方法,实现协议,添加属性(关联对象)。不能增加实例变量。

通过编译成C代码可以看的更清晰

clang -rewrite-objc MyClass.m

  • category注意事项
    • 1)、category的方法没有“完全替换掉”原来类已经有的方法,也就是说如果category和原来类都有methodA,那么category附加完成之后,类的方法列表里会有两个methodA
    • 2)、category的方法被放到了新方法列表的前面,而原来类的方法被放到了新方法列表的后面,这也就是我们平常所说的category的方法会“覆盖”掉原来类的同名方法,这是因为运行时在查找方法的时候是顺着方法列表的顺序查找的,它只要一找到对应名字的方法就会停止。

+load

  • 1)、附加category到类的工作会先于+load方法的执行
  • 2)、+load的执行顺序是先类,后category,而category的+load执行顺序是根据编译顺序决定的。
    目前的编译顺序是这样的:
代码形式 编译器/运行期 实例变量 和类的关系 类的源代码
@interface MainViewController ()<UIGestureRecognizerDelegate 编译器决定 可以增加实例变量 是类的一部分,跟类的产生而产生,随类的消亡一起消亡.用来隐藏类的私有信息。 需要类的源代码
@interface MainViewController (Gesture) 运行期决定 不可以增加实例变量,但是可以绑定一个数据对象 不是类的组成部分,由运行期修改类的方法数组增加的方法 不需要类的源代码

category通过关联对象增加属性的原理

运行时通过AssociationsManager里面是由一个静态AssociationsHashMap来存储所有的关联对象的,这是一个全局的map,key是关联对象的指针地址,value是另外一个AssociationsHashMap,里面保存了关联对象的kv对。

KVC实现原理

KVC运用了一个isa-swizzling技术。isa-swizzling就是类型混合指针机制。KVC主要通过isa-swizzling,来实现其内部查找定位的。isa指针,如其名称所指,(就是is a kind of的意思),指向维护分发表的对象的类。该分发表实

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值