美文网首页iOS面试题
iOS底层部分面试题

iOS底层部分面试题

作者: iOS心安 | 来源:发表于2021-07-08 15:54 被阅读0次

Runtime Asssociate方法关联的对象,是否需要在dealloc中释放?

答:不需要释放

分析

我们知道当一个对象销毁的时候会调用dealloc方法,那么我们先看下dealloc都进行了哪些操作。

dealloc函数调用了_objc_rootDealloc函数


63f5abe78c674cdeaff67d0f1bb784f1_tplv-k3u1fbpfcp-watermark.png

_objc_rootDealloc函数调用rootDealloc函数

void
_objc_rootDealloc(id obj)
{
    ASSERT(obj);

    obj->rootDealloc();
}

rootDealloc函数查看

inline void
objc_object::rootDealloc()
{
    if (isTaggedPointer()) return;  // fixme necessary?

    if (fastpath(isa.nonpointer  &&  
                 !isa.weakly_referenced  &&  
                 !isa.has_assoc  &&  
                 !isa.has_cxx_dtor  &&  
                 !isa.has_sidetable_rc))
    {
        assert(!sidetable_present());
        free(this);
    } 
    else {
        object_dispose((id)this);
    }
}

从rootDealloc函数中我们看到了判断isa相关属性的地方,实际上当一个对象存在会进入else中,即****object_dispose函数
object_dispose函数查看

id 
object_dispose(id obj)
{
    if (!obj) return nil;

    objc_destructInstance(obj);    
    free(obj);

    return nil;
}

通过objc_destructInstance函数找到对象,然后free,我们看objc_destructInstance函数

objc_destructInstance函数

ede3ce5f541e4a46b021579178faf33d_tplv-k3u1fbpfcp-watermark.png
重点查看_object_remove_assocations函数

_object_remove_assocations函数分析


45bcdc39e4524fb2b144f57016bd5edb_tplv-k3u1fbpfcp-watermark.png

类、分类方法同名时调用顺序是怎样的?

当非+load方法同名时,分类的方法在类的方法前面(注意不是覆盖),因为分类的方法是在类realize之后 attach进去的,所以 优先分类,其次类
当+load方法同名时,优先类,其次分类

3分类与类的扩展

分类

专门用来给类添加新的方法
不能添加属性,但是可以通过runtime动态添加属性(因为我们在前面的篇章中分析过,分类底层代码中有属性列表)
分类中@property定义的变量只会生成setter以及getter方法的声明,但是不会生成对应的方法实现以及带有下划线的成员变量

类的扩展

可以添加给类添加属性,但是属于私有变量,比如ViewController的.m文件中@property定义的变量只能是这个ViewController的.m文件使用
添加的方法也是私有方法

什么是Runtime?

runtime是由C和C++汇编实现的一套API,为OC语言添加了面向对象和运行时功能。

运行时:将数据类型的确定由编译阶段推迟到了运行阶段。我们平时所写的OC代码,最终转换为runtime的C语言代码。

方法的本质是什么?SEL、IMP是什么?两者之间的关系是什么?

方法的本质

方法的本质是消息的发送,涉及到消息发送的流程有

快速查找:objc_msgSend ~cache_t中查找
慢速查找:递归自己以及父类查找,即lookUpImpOrForward
动态解析:当查找不到消息时执行动态解析,即resolveInstanceMethod
消息快速转发:当动态解析也没有找到消息,则进行消息快速转发,即forwardingTargetForSelector
消息慢速转发:消息快速转发没有找到消息,则进行消息慢速转发,即mesthodSignatureForSelector & forwardInvocation
以上流程均没有找到消息则crash

SEL、IMP

sel:方法编号,类比一本书的目录
imp:方法函数指针地址,类比一本书的页数
sel与imp关系:sel是方法编号,通过sel找到imp的函数指针地址,通过imp就能找到函数的实现

能否向编译后的类中添加实例变量?能否向运行时创建的类添加实例变量?

不能向编译后的类中添加实例变量,因为编译后实例变量存储到 ro 中,一旦编译完成,内存结构就完全确定了,无法再次修改
只要类还没有注册到内存还是可以添加的
可以添加属性与方法
点击此处获得更多学习资料

收录原文地址

相关文章

网友评论

    本文标题:iOS底层部分面试题

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