zoukankan      html  css  js  c++  java
  • OC之runtime面试题(一)

    对于LBPerson类,代码如下

    @interface LBPerson : NSObject
    @property (nonatomic, copy) NSString *name;
    
    - (void)test;
    @end
    @implementation LBPerson
    - (void)test {
        NSLog(@"name = %@", self.name);
    }
    @end

    外面存在以下调用代码,问能否调用成功,如果能打印结果是什么

    - (void)viewDidLoad {
        [super viewDidLoad];
        NSString *test = @"hhhhh";
        id cls = [LBPerson class];
        void *obj = &cls;
        [(__bridge id)obj test];
        
    }

    运行之后打印结果如下:

    name = hhhhh

    从打印结果看,调用成功了,但是打印了viewDidLoad中test的变量的值

    首先我们分析为什么能调用成功,对于一般的LBPerson中test的调用:

    LBPerson *person = [[LBPerson alloc] init];
    [person test];

    对于正常的person对象调用test的方式,是通过person对象的isa指针,找到LBPerson类进行调用的

    对于[(__bridge id)obj test]的调用,对于上述代码的声明obj->cls->[LBPerson class],在[obj test]调用过程中,会根据obj的指向,取出obj指向地址中前八个字节,而obj指向cls刚好,cls八个字节全部指向[LBPerson class],这也就是能调用成功的原因

    下面分析打印结果,打印结果为name = hhhhh

    上述代码中内存分配如下图所示:

    最终调用test 传入的是cls的地址,而正常的person对象调用时候,取name的值的时候,是根据person对象的地址加八个字节。obj调用的时候相当于在cls地址的基础上加八个字节,刚好是test变量的地址,所以打印的是test变量的值

  • 相关阅读:
    IDEA中好用的插件
    Win10安装Docker
    win10系统关闭此电脑的文件夹
    postgreSQL主键自增长
    【设计模式】工厂模式
    vue2.0实现倒计时的插件(时间戳 刷新 跳转 都不影响),转载
    springCloud中的组件学习
    使用springBoot+jsp+redis解决单一用户问题
    使用HtmlUnit动态获取网页数据
    java爬取网站中所有网页的源代码和链接
  • 原文地址:https://www.cnblogs.com/muzichenyu/p/14210494.html
Copyright © 2011-2022 走看看