Objective-C中脆弱的基类是什么?

时间:2013-11-22 06:55:19

标签: objective-c oop inheritance base-class

我正在读一本关于对象的书。在谈到遗产时,这本书说:

  

方法使用self参数查找它们的实例变量   使用

     

Objective-C编译器知道实例变量的布局   一个对象,因为它已经看到了每个的@interface声明   这些课程。

     

有了这些重要的知识,编译器就可以生成要查找的代码   任何实例变量。

然后它说这会导致脆弱的基类问题:

  

编译器通过使用“基础加偏移”机制来发挥其魔力。

     

给定对象的基址 - 即第一个实例变量的第一个字节的内存位置 - 编译器可以通过向该地址添加偏移量来查找所有其他实例变量。

     

当您在方法中访问某个实例变量时,编译器会生成代码以获取自保持的值,并添加偏移量的值(在本例中为4)以指向存储变量值的位置。

     

这会导致长期出现问题。

     

这些偏移现在硬编码到编译器生成的程序中。

     

即使Apple的工程师想要向NSObject添加另一个实例变量,他们也不能,因为会改变所有实例变量偏移

     

这称为脆弱的基类问题

     

Apple已经使用Leopard引入的新64位Objective-C运行时解决了这个问题,它使用间接方式来确定ivar位置。

我不明白为什么在NSObject中添加实例变量会导致问题。

如果NSOject发生变化,我们不能只重新编译程序,以便偏移量发生变化吗?

编辑:如果我们不重新编译,现有代码会失败吗?

2 个答案:

答案 0 :(得分:2)

如果Apple向NSObject添加了一个ivar,所有的子类都需要重新编译,这意味着一个非常接近所有Objective-C代码的100%的数字

你现在看到问题吗?

解决这个问题并非不可能,只是需要让每个开发人员重新编译他们的代码库,但同时每个Objective-C程序都会被破坏。

作为进一步的参考,这是Greg Parker关于这个主题的一篇非常好的文章:http://www.sealiesoftware.com/blog/archive/2009/01/27/objc_explain_Non-fragile_ivars.html

答案 1 :(得分:2)

是的,重新编译可以解决问题,但在重新编译之前,您的程序将被破坏。

想象一下,您编译的应用程序定位到10.4。编译器查看NSObject的标题,并确定子类中每个ivar的适当偏移量。然后10.5出来,他们将新的ivars添加到NSObject。在10.5上运行你的应用程序的任何人都会遇到问题,因为Foundation框架(包括NSObject)是针对10.5 SDK编译的,而你的应用仍然依赖于10.4 SDK中的布局。

脆弱的基类问题意味着Apple无法更改任何框架类的大小而不会崩溃没有为新SDK重新编译的每个应用程序。在理想的世界中,开发人员总是会及时发布更新,这不是现实。因此,在脆弱的基类问题得到解决之前,Apple的双手并列。