为什么转换类型不会改变 isa 指针。

3
id a = self->isa;
id b = ((NSObject*)self)->isa;

a和b持有相同的值。

现在假设一个指针是相同的,为什么

[(Animal*)Person speakEnglish];

出现错误?我认为强制类型转换会改变isa指针,因为如果我将子类转换为父类,就不能再调用子类的方法了,而方法调用搜索是基于isa指针的。

我想知道如何实现方法选择器,即使一个实例的isa指针指向Person,如果我调用该实例的Person方法,仍然会出现错误。


1
你是在谈论运行时错误还是编译器错误/警告?强制转换除了向编译器提供信息外并没有做任何事情。 - jrturton
强制类型转换与isa没有任何关系。通常情况下,isa不能/不应该被修改(除非你知道自己在做什么)。Objective-C消息分发是在运行时完成的,而C++中非虚函数分发是在编译时完成的。 - Bryan Chen
1个回答

0

我假设Animal没有方法-speakEnglish,但是Person的原始类有这个方法。

然后,你会得到一个编译器错误,因为该方法未声明。请注意,(如@jrturton和@xlc0212所提到的)编译器不知道运行时的任何信息。

可能在运行时对象具有可调用的选择器:

 [(Animal*)Person performSelector: @selector(speakEnglish)];

这个使用运行时数据。更准确地说,它检查方法实现是否与此选择器连接,并调用此实现。

然而,编译器无法知道,因为编译器依赖于静态类型信息。因此,您应该提供正确的类型信息。但是您却相反:丢弃了正确的类型。


动物是一个类,所以方法应该是 +speakEnglish 吗? - jaume
@jaume:不,除非你真的想让类对象(而不是类的实例对象)执行该方法。关键是,与OP声称的相反,强制转换与isa无关;这是静态类型的问题。 - Matthias
我最初认为OP是在问为什么将类Person强制转换为其父类Animal失败,因为Person是大写的,按照惯例是一个类。现在我认为OP可能意味着[(Animal *)person speakEnglish],其中person是类Person的实例。无论如何,正如你所说,这与isa无关。 - jaume

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接