Untitled

我们看到划线部分有一个方法调用,看到这个我们会产生两个疑惑

  1. 方法可以被调用吗?
  2. 如果可以调用printName方法会打印什么

我们运行项目看看他的运行结果

Untitled

通过控制台打印,我们知道printName被调用,并打印了当前ViewController实例对象,那么为什么呢?

一、方法为什么可以被调用?

我们声明一个实例对象和代码中对比起来看一看

id cls = [MLDog class];
void *obj = &cls;

MLDog *dog = [[MLDog alloc] init];

从前面的学习我们知道实例变量dog在内存中是一个struct

{
	Class isa;
	NSString *_name;
}

如果有C语言基础的同学,一定知道结构体的第一个成员的地址适合结构体地址是相同的,所以dog局部变量指向的指针也就是isa的地址。

Untitled

如上图所示,obj 在这里也可以看做是一个MLDog的实例对象,也就是一个消息接受者,他在进行objc_msgSend发送消息时是可以根据obj找到cls(相当于isa),然后通过cls找到[MLDog class]。

所以[(__bridge id)obj printName]是可以被调用成功

二、为什么打印ViewController实例对象

函数栈中的地址分配

在探究之始,我们先了解一下方法中局部变量的内存分配是啥样的