我在读一本object-c的书。当谈到继承时,书上说:
方法使用自参数查找实例变量。
使用。
objective-c编译器知道
一个对象,因为它已经看到了每个接口的@接口声明。
这些课程。
利用这些重要知识,编译器可以生成代码来查找。
任何实例变量。
然后说这会导致脆弱的基类问题:
编译器通过使用“base plus offset”机制来实现其魔力。
给定一个对象的基地址,即第一个实例变量的第一个字节的内存位置,编译器可以通过向该地址添加偏移量来查找所有其他实例变量。
当您访问某个方法中的某个实例变量时,编译器会生成代码来获取self持有的值,并将偏移量(在本例中为4)的值相加,以指向存储该变量值的位置。
这会导致时间问题。
这些偏移量现在硬编码到编译器生成的程序中。
即使苹果的工程师想在nsobject中添加另一个实例变量,他们也不能,因为这会改变所有实例变量的偏移量。
这被称为脆弱的基类问题。
Apple已经用Leopar引入了新的64位Objy-C运行时修复了这个问题,它使用间接来确定IVAR位置。
我不明白为什么在nsobject中添加实例变量会导致问题。
如果项目改变了,我们就不能重新编译程序,使偏移量相应地改变吗?
如果我们不重新编译,现有的代码会失败吗?
最佳答案
是的,重新编译可以修复问题,但是在重新编译之前,程序将被破坏。
假设你的应用程序目标是10.4。编译器查看nsobject的头并找出子类中每个ivar的适当偏移量。然后10.5出来了,他们给nsobject添加了新的ivar。任何在10.5上运行应用程序的人都会遇到问题,因为基础框架(包括nsobject)是根据10.5sdk编译的,而应用程序仍然依赖10.4sdk中的布局。
脆弱的基类问题意味着,苹果不会改变任何框架类的大小,而不会破坏没有为新SDK重新编译的每一个应用程序。在理想的情况下,开发人员总是会及时发布更新,这不是事实。因此,在脆弱的基类问题被解决之前,苹果的手是绑在一起的。