对于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变量的值