OC语言

作者: BigBossZhu | 来源:发表于2019-08-14 17:29 被阅读0次

    1. 分类?做了哪些事情?
    1. 声明私有方法
    2. 分解类文件(体积庞大,按功能分类)
    3. 将Framework的私有方法公开化.未公开的方法可以重写调用
    特点:
    运行时决议.在运行时通过runtime动态添加
    可以为系统类添加分类.

    分类中可以添加哪些内容?
    1. 可以添加实例方法
    2. 可以添加类方法
    3. 协议
    4. 属性(只申明set,get方法并没有添加实例变量)

    分类结构:

        name:分类名称
        class:表示分类宿主类
        method_list_t *instanceMethods:实例方法列表
        method_list_t *classMethods:类方法列表
        method_list_t *protocols:协议列表
        method_list_t *instanceProperties:实例属性列表
    

    源码分析:
    1. 最先访问最后编译的分类.最后编译的分类中的方法会覆盖之前的方法.生效.
    2. 分类方法会'覆盖'宿主类方法,分类方法位于打头的位置会被优先实现.
    3. 名字相同的分类会引起编译报错.
    关联对象:怎样为分类添加成员变量.
    能为分类添加成员变量,但是是通过关联对象的技术.
    id objc_getAssociatedObject()
    void objc_setAssociatedObject()
    void objc_removeAssociatedObject()

    关联对象的本质:
    关联对象由AssociationsManager管理并在AssociationsHashMap中存储.所有对象的关联内容都在同一个全局容器中.

    2. 扩展:
    1. 一般用扩展做什么?
    1. 声明私有属性
    2. 声明私有方法
    3. 申明私有成员变量(开发中一般直接放在.m文件中)
    特点:
    编译时决议
    只以声明的形式存在,多数情况下寄生在宿主类.m文件中
    不能为系统类添加扩展

    3. 代理:
    准确的说是一种设计模式.(代理模式)
    @protocol
    传递方式1对1.通知时1对多的.
    单层传递

    代理的工作流程:
    协议.代理方,委托方.
    可以定义属性和方法
    代理方必须要都实现协议的方法吗?
    不一定需要.声明的方法require必须实现.option可以实现可以不实现.
    注意: 1. 一般申明引用代理方为weak被委托方持有,从而规避循环引用

    4. 通知:
    1对多(一个通知多个接收,但是注意delloc中释放通知)
    使用观察者模式设计模式实现
    跨层传递
    具体实现原理:
    notification_map为一个数组元素为字典,key:name对应value:数组内含多个观察者.

    5. KVO:
    什么是KVO:Key-value observing

    1. KVO是观察者模式的一种实现.
    2. 系统采用isa混写(isa-swizzling)来实现KVO.
      isa混写技术是什么?怎样实现的?
      当我们调用A类的addObserverForKeyPath方法的之后系统会在运行时动态创建一个当前类的子类(Notification_A),这个子类会重写监听属性的set方法来通知所有观察者,这个时候会将原来类的isa指针指向新创建的这个子类,把isa的指向进行修改实际上就是isa混写技术.
      通过代码打印class在addObserverForKeyPath之后类名改变发现确实是这样的
      重写setter方法具体实现是怎么样的呢?
      首先调用willChangeValueForKey.再调用父类的setValue方法(作用:不会对父类setter方法产生干扰),再调用didChangeValueForKey方法(此方法会触发kvo回调).
      问题:通过KVC设置和成员变量赋值能否生效?
      注意:KVC生效,成员变量不生效.为啥?涉及到KVC的实现和原理(KVC会调用A类的setter方法).
      问题:手动KVO是怎么样的?
      在复制前后添加willChangeValueForKey,和didChangeValueForKey方法.就能模拟系统KVO实现.

    6. KVC:
    什么是KVC:Key-value coding键值编码技术.
    KVC编码技术会破坏面向对象的思想,尽量少使用这种编码技术.
    valueForKey系统实现流程:
    首先查找key对应的实例变量是否有getter方法,没有,会查找是否存在此实例变量,没有继续调用valueForUndefinedKey.抛出NSUndefineKeyException异常结束调用.(注意此处使用的是模糊查找类似key也能够查找到).
    setValueForKey类似.只是是set方法.

    7. 属性关键字:

    1. 读写权限(readonly,readwrite默认)
    2. 原子性(atomic默认,nonatimic).赋值和获取是线程安全的.
    3. retain/strong,assign/unsafe_unretained,weak,copy
      assgin和weak关键字的区别有哪些呢?
      assgin常用修饰的是基本数据类型但也可修饰对象,不改变引用计数,再被释放会仍然指向原对象.
      weak修饰的是对象,不改变引用计数.所指对象再被释放之后会自动置为nil.

    ** copy关键字. **
    浅拷贝:内存地址复制.增加被拷贝指针的引用计数.
    深拷贝:产生新的内存分配.新的指针指向新的内存空间,只是内容相同.
    如何区分深拷贝和浅拷贝?
    深拷贝会产生新的内存空间.浅拷贝影响了引用计数.(注意mutableCopy拷贝一定是可变对象,只有不可变对象copy才是浅拷贝其他都是深拷贝).

    copy修饰可变数组会产生什么问题.
    会导致程序异常,如果指针指向可变对象copy会变成不可变,如果指向不可变对象会变成不可变.但是会调用可变数据内部方法,就会产生异常.

    相关文章

      网友评论

          本文标题:OC语言

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