Lui*_*BOL 5 objective-c objective-c-runtime
在Objective-C的遗留版本中,objc_class结构实现如下:
struct objc_class {
Class isa;
Class super_class;
const char *name;
long version;
long info;
long instance_size;
struct objc_ivar_list *ivars;
struct objc_method_list **methodLists;
struct objc_cache *cache;
struct objc_protocol_list *protocols;
};
Run Code Online (Sandbox Code Playgroud)
因此,表示对象的结构存储指向对象类的指针,指向对象超类的指针,对象的类名,对象的版本,信息和实例大小,对象的实例变量列表,对象的方法列表,对象的缓存和对象的协议列表.在表示对象的结构中存在这些字段是非常容易理解的,因为它们中的每一个都存储有关该对象的信息.
但是,相同的struct objc_class的Objective-C 2.0实现是这样的:
struct objc_class {
Class isa;
};
Run Code Online (Sandbox Code Playgroud)
因此,在这个版本的objc_class中,struct中只有一个字段:指向对象类结构的指针.
那么,我的问题是,对象的其他信息是如何存储在Objective-C 2.0中的,因为结构中只有一个表示对象的字段?
这一切都在新的(好的,不再那么新的)非脆弱的ABI.
基本上,不是像以前那样将iVar存储在结构体内(如果超类改变它的iVar布局会破坏继承),编译器会将iVar重定向放入另一层,类似于objc_setAssociatedObject运行时.
这允许一些有趣的场景.考虑以下:
@interface A { // part of libA.a
id var1;
int var2;
float var3;
}
@end
@interface B : A { // part of libB.a
id var4;
}
@end
Run Code Online (Sandbox Code Playgroud)
现在,如果有一段时间我们需要更改类A,我们确定我们需要更高的精度var3(long double例如将其转换为a )?
在较旧的,脆弱的ABI中,我们会被搞砸,直到libB更新的制造者.然而,有了这个新的,非脆弱的ABI,我们可以灵活地改变所有这些,同时libB仍然有效.
虽然理论上这可能会在几个周期内变慢,但它增加了在运行时查找iVars的更简单方法,更灵活的子类化以及对不同类型的iVar的支持(__weak例如).
| 归档时间: |
|
| 查看次数: |
347 次 |
| 最近记录: |