iOS 基础知识(一)

作者: 小和大大 | 来源:发表于2022-06-24 18:00 被阅读0次
    image

    目录

    1. 一个NSObject对象占用多少内存?
    2. 对象的isa指针指向哪里?
    3. OC的类信息存放在哪里?
    4. iOS用什么方式实现对一个对象的KVO?(KVO的本质是什么?)
    5. KVC
    6. Category
    7. +load方法和+initialize方法
    8. Block
    9. _ _weak

    1. 一个NSObject对象占用多少内存?

    系统分配了16个字节给NSObject对象(通过malloc_size函数获得),但NSObject对象内部只使用了8个字节的空间(64bit环境下,可以通过class_getInstanceSize函数获得)。

    2. 对象的isa指针指向哪里?

    instance对象的isa指向class对象;
    class对象的isa指向meta-class对象;
    meta-class对象的isa指向基类的meta-class对象;

    image

    3. OC的类信息存放在哪里?

    对象方法、属性、成员变量、协议信息,存放在class对象中;
    类方法,存放在meta-class对象中;
    成员变量的具体值,存放在instance对象;

    4. iOS用什么方式实现对一个对象的KVO?(KVO的本质是什么?)

    执行addOberser时 利用RuntimeAPI动态生成一个子类,并且让instance对象的isa指向这个全新的子类,当修改instance对象的属性时,会调用Foundation的_NSSetXXXValueAndNotify函数:
    -> willChangeValueForKey:
    -> 调用父类原来的setter
    -> didChangeValueForKey:
    -> 内部会触发监听器(Oberser)的监听方法( observeValueForKeyPath:ofObject:change:context:)

    • 如何手动触发KVO?
      手动调用willChangeValueForKey:和didChangeValueForKey:
    • 直接修改成员变量会触发KVO么?
      不会触发KVO

    5. KVC

    KVC的全称是Key-Value Coding,俗称“键值编码”,可以通过一个key来访问某个属性。

     常见的API
     - (void)setValue:(id)value forKeyPath:(NSString *)keyPath;
    - (void)setValue:(id)value forKey:(NSString *)key;
    - (id)valueForKeyPath:(NSString *)keyPath;
    - (id)valueForKey:(NSString *)key; 
    
    
    • 通过KVC修改属性会触发KVO么?
      会触发KVO
    image image

    6. Category

    • 1.Category的底层结构
    image
    • 2.Category的加载处理过程
    image
    • 3.如何实现给分类“添加成员变量”?
    image
    • 4.关联对象的原理
    image

    7. +load方法和+initialize方法

    image image

    8. Block

    block本质上是封装了函数调用以及函数调用环境的OC对象,它内部也有个isa指针。

    • 为了保证block内部能够正常访问外部的变量,block有个变量捕获机制
    image
    • 3种block类型
    image image
    • _ _block修饰符
    image
    • _ _block的内存管理
    image

    9. _ _weak

    weak 关键字的作用弱引用,所引用对象的计数器不会加一,并在引用对象被释放的时候自动被设置为 nil。

    weak是Runtime维护了一个hash(哈希)表,用于存储指向某个对象的所有weak指针。weak表其实是一个hash(哈希)表,Key是所指对象的地址,Value是weak指针的地址(这个地址的值是所指对象指针的地址)数组。

    • weak释放为nil的过程:

    1、调用objc_release
    2、因为对象的引用计数为0,所以执行dealloc
    3、在dealloc中,调用了_objc_rootDealloc函数
    4、在_objc_rootDealloc中,调用了object_dispose函数
    5、调用objc_destructInstance
    6、最后调用objc_clear_deallocating:

    1、从weak表中获取废弃对象的地址为键值的记录
    2、将包含在记录中的所有附有 weak修饰符变量的地址,赋值为nil
    3、将weak表中该记录删除
    4、从引用计数表中删除废弃对象的地址为键值的记录


    推荐学习资料:

    Swift从入门到精通
    每周一道算法题
    恋上数据结构与算法(一)
    恋上数据结构与算法(二)

    如果需要跟我交流的话:
    ※ Github: https://github.com/wsl2ls
    ※ 简书:https://www.jianshu.com/u/e15d1f644bea

    原文链接:https://www.jianshu.com/p/b184a43ec74a

    相关文章

      网友评论

        本文标题:iOS 基础知识(一)

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