我到处都读到Objective-C具有真正的动态绑定,而C ++只有Late绑定。不幸的是,没有一本书继续清楚地解释它或讨论底层实施。例如,C ++使用虚拟表。 Objective-C怎么样?
答案 0 :(得分:8)
http://www.gnu.org/software/gnustep/resources/ObjCFun.html有很好的描述。
基本上,动态绑定意味着在实际进行方法调用时,决定调用什么方法。如果您愿意,该方法可以在那时动态选择。
编辑:根据我的理解,这里有更多细节。我不保证这是完全正确的,但它应该是正确的。 Objective C中的每个对象都是一个结构体,其第一个成员名为isa
,是指向类的指针。每个类本身都是一个传统的布局对象:
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;
};
在运行时,这里是方法查找发生的伪代码:
Follow isa to find the class
if implementation = class.lookup_method(method):
call implementation
else if get_implementation = class.lookup_method(forwardInvocation):
implementation = get_implementation(method)
if implementation:
call implementation
else:
raise runtime error
else:
raise runtime error
lookup_method
如何运作?
def lookup_method (class, method):
if method in class.objc_cache:
return implementation from objc_cache
else if method in class.objc_method_list:
cache implementation from objc_method_list
return implementation
else if implementation = class.super_class.lookup_method(method):
cache implementation
return implementation
else:
return null
回答这个显而易见的问题,是的,这比C ++的虚拟表慢得多。根据基准测试,速度约为1/3。每个Objective C文本都会紧随其后,因为在现实世界中,方法查找速度几乎不会成为瓶颈。
这比C的方法查找灵活得多。例如,您可以使用forwardInvocation
使无法识别的方法转到变量中的对象。这种委托可以在不知道该对象在运行时的类型或它将支持的方法的情况下完成。您还可以向类添加方法 - 即使在运行时也可以 - 无需访问源代码。您还可以对类和方法进行丰富的运行时内省。
显而易见的另一面是,任何C ++程序员都会上下跳动,就是你已经抛弃了编译时类型检查的希望。
这是否可以解释这些差异,并为您提供足够的细节来了解正在发生的事情?
答案 1 :(得分:0)
事实上,动态绑定和后期绑定都是相同的。我们有静态绑定或早期绑定,它检查编译时发生的问题(关于变量,表达式等的错误),这些信息存储在v表(虚方法表)中。后期绑定的作用是它只是将方法与v表中的方法绑定在一起。