美文网首页iOS Kit
iOS底层学习24 -- class和super的面试题

iOS底层学习24 -- class和super的面试题

作者: 恋空K | 来源:发表于2020-11-12 23:47 被阅读0次
    相关方法的底层实现
    - (Class)class {
    return object_getClass(self); // 把消息接收者传进去,获取消息接收者的类(
    self就是class方法当前的调用者,也就是消息接收者)
    }
    



    MJPerson 跟[MJPerson class] 是一个意思,都是代表类对象
    元类对象跟类对象是不一样的
    




    上面注释掉的4行代码跟下面的4行代码是一样的

    =============================super面试题================





    person这个指针变量里面存储的是isa这个指针变量的地址值,isa这个指针变量里面存储的又是
    [MJPerson class]的地址值。
    平时我们正常调用方法是怎么找到对应的isa的呢?
    答:从表面上看是 person ->isa ,这样找到isa,但实际上本质是,取出person指针所指向的那一块内存
    空间的前8个字节,也就是isa指针(isa转成汇编本质,实际上就是拿第一个成员person ->第一个成员,然后
    找到类对象),然后通过isa就能找到对应的类对象,就可以开始查找方法,查找到后开始调用了。
    
    [person 方法]为什么能够调用成功?
    答:通过person这个指针找到对应的实例对象的内存(也就是person这个指针变量所指向的内存空间)
    并取出最前面的8个字节,因为最前面8个字节就是isa指针。取出isa指针后(或者取出最前面8个字节以后)
    就能找到类对象,去缓存里面找方法或者方法列表中找方法。
    上图中obj能够调用成功,是因为obj指向的cls(也就是这块内存)前8个字节(存储的内容)刚好是
    MJPerson类对象的内存地址值
    

    函数调用问题:


    函数里面局部变量分配在栈空间
    左边这块区域是我们这个函数的栈空间,[MJPerson class] 和@“123”在全局区
    self.name 就是获取_name,怎么找到_name,那不就是这么去找嘛self -> _name,而self就是当前方法的调用者,此时print方法的调用者是obj,所以此时的self就是obj
    找_name的本质:self指向那个结构体,self存储的地址值就是整个结构体的地址值,相当于self存储的地址值就是isa变量的地址值。所以self -> _name,也就是找_name的时候,忽略前面8个字节,找下面8个字节,就能找到_name了。找内存的本质,就是找到内存地址,再取出内存地址里面的值
    [super viewDidLoad]会先定义一个隐藏的局部结构体变量。如果注释掉[super viewDidLoad],就会出现坏内存访问,因为查找_name的时候,不知道找谁了




    ===================验证=========



    此时person实例对象对应的结构体是{isa, country, age}也就是属性的定义顺序,决定了属性在结构体里面的位置顺序

    =====================


    验证1
    验证1
    验证1 验证2
    验证2
    验证2

    从第二个成员的父类开始搜索方法

    相关文章

      网友评论

        本文标题:iOS底层学习24 -- class和super的面试题

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