我知道在Objective C中,每个对象都有前4个字节[取决于处理器的类型]作为存储在其中的isa指针,它告诉它属于哪个类以及用于解析选择器的地址的调度表一个功能。
我想知道的是,如何在这些方法中存储和访问数据成员。 self在被调用的每个函数中作为隐式对象传递。
我们使用setter n getters来处理其他成员函数中的数据成员,这是一种很好的做法,
但是当我们直接引用初始化程序或访问者中的数据成员时,它们是如何被访问的。它们是在编译时用其他地址替换的吗?
答案 0 :(得分:3)
实际上,内存布局是特定于实现的,但http://algorithm.com.au/downloads/talks/objective-c-internals/objective-c-internals.pdf应该让您对对象数据和对象消息的内部工作有一个很好的了解。
当您使用直接成员访问时,基本上发生的是您直接从作为实际对象的“struct”获取。也就是说,编译器基本上只是在对象/结构的地址中添加一个偏移量并读取该内存地址的内容。
也许我应该补充一点,这是从XCode逆向工程而不是用我能找到的任何规范写的,所以根据这种行为很可能是一个坏主意。由于不允许外部访问iVar,因此决定基本上由编译器决定,并且可以随时更改。
编辑:正如@FrederickCheung所指出的,Objective C 2.0可能已经改变了这种行为。
答案 1 :(得分:2)
它不像编译时偏移计算那么简单,至少在64位OS X和iOS运行时不在目标C 2.0中。这些支持超类更改其实例变量布局,而不会破坏通过添加一层间接层而针对旧布局编译的子类。
运行时api docs描述了可以用来设置实例变量等的API,但没有详细说明它们的实现。