标签:objective c 黑马程序员
当调用对象方法时,编译器都会默认传入一个指向本对象的指针。所以不同的对象都会调用到正确的成员变量。这个指针就是self,它的值就是new时在堆中分配内存的首地址。那么这个self在方法调用时是存储在栈中么?上代码调试来看一下
#import <Foundation/Foundation.h> @interface Person : NSObject { int _age; } - (void)setAge:(int)age; - (int)age; - (void)test:(int)age; @end int main(int argc, const char * argv[]) { Person *p = [Person new]; NSLog(@" p = %p", p); [p setAge:10]; [p test:20]; return 0; } @implementation Person - (void)setAge:(int)age { _age = age; } - (int)age { return _age; } - (void)test:(int)age { int _age = 20; NSLog(@"局部变量_age = %d", _age); NSLog(@"年龄:%d", self->_age); } @end
在运行到_age=age;语句时断下。观察反汇编代码和相关寄存器值
我们发现
寄存器rsi中的值和self中的值 是一样的。 edx = 10(也就是rdx寄存器的低32位); rsi = 8;
单步下向执行一条汇编语句。断在popq
%rbp处。此时movl %edx, (%rsi,%rdi) 已经执行完毕。而断点所指向的语句是将要执行但还未执行的语句
打开self所指向的内存窗口再次观察
我们发现self + 8地址处4字节空间已经被赋值为 00 00 00 0A;所以_age最终被设置为10;也就是说成员变量的地址是在self+8处开始的。
那这8个字节又是什么呢
这8字节就是isa指针。NSObject.h头文件中声明
@interface NSObject <NSObject> { Class isa OBJC_ISA_AVAILABILITY; }而Class在objc.h中是这样声明的
typedef struct objc_class *Class;
通过以上观察,调用对象方法时传入的self参数是存储在CPU
寄存器当中的
标签:objective c 黑马程序员
原文地址:http://blog.csdn.net/xi_niuniu/article/details/45030761