- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我正在读一本关于 object-c 的书。谈到继承,书上说:
Methods use the self parameter to find the instance variables they use.
The Objective-C compiler knows the layout of the instance variables in an object because it has seen the @interface declarations for each of these classes.
With this important knowledge, the compiler can generate code to find any instance variable.
然后它说这会导致脆弱的基类问题:
The compiler works its magic by using a “base plus offset” mechanism.
Given the base address of an object—that is, the memory location of the first byte of the first instance variable—the compiler can find all other instance variables by adding an offset to that address.
When you access some instance variable in a method, the compiler generates code to take the value that self holds and add the value of the offset (4, in this case) to point to the location where the variable’s value is stored.
This does lead to problems over time.
These offsets are now hard-coded into the program generated by the compiler.
Even if Apple’s engineers wanted to add another instance variable to NSObject, they couldn’t, because that would change all of the instance variable offsets.
This is called the fragile base class problem.
Apple has fixed this problem with the new 64-bit Objective-C runtime introduced with Leopard, which uses indirection for determining ivar locations.
我不明白为什么在 NSObject 中添加实例变量会导致问题。
如果 NSOject 发生变化,我们是否可以重新编译程序,使偏移量相应地发生变化?
编辑:如果我们不重新编译,现有代码会不会失败?
最佳答案
是的,重新编译会解决问题,但在您重新编译之前,您的程序会被破坏。
假设您针对 10.4 编译您的应用。编译器查看 NSObject 的 header 并找出子类中每个 ivar 的适当偏移量。然后 10.5 出来了,他们向 NSObject 添加了新的 ivars。任何在 10.5 上运行您的应用程序的人都会遇到问题,因为 Foundation 框架(包括 NSObject)是针对 10.5 SDK 编译的,而您的应用程序仍然依赖于 10.4 SDK 中存在的布局。
脆弱的基类问题意味着 Apple 无法更改任何框架类的大小而不会使所有未针对新 SDK 重新编译的应用程序崩溃。虽然在理想世界中,开发人员总是会及时发布更新,但事实并非如此。因此,在脆弱的基类问题得到解决之前,Apple 的双手都被束缚住了。
关于objective-c - Objective-C 中的脆弱基类是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20138864/
我是一名优秀的程序员,十分优秀!