我遇到了一个非常奇怪的行为,我无法理解。我有一个 Texture
contentWidth
的类(class)int
类型的属性.此类包含在 Image
中具有 width
的类int
类型的属性. width
的 Image
简单地计算为 contentWidth
底层纹理:
- (int) width
{
return texture.contentWidth;
}
现在
Image
被 Button
使用想要读取图像大小的类(通过组合,而不是继承):// image is of type ‘id’
int width = [image width];
int height = [image height];
问题是
height
变量设置得很好,而 width
变量包含 NaN
(–2147483648)。我检查了尺寸——它们大约是 200×100 左右,与 int
相去甚远。限制。 Xcode 调试器工具提示也在 Texture
中显示了这两个属性。正确地,只有在宽度通过两个访问器之后,数字才会出现乱码。对象没有被释放。我错过了什么?更新:我在
Image
中扩展了访问器上课看看问题出在哪里:- (int) width
{
const int w = texture.contentWidth;
return w;
}
现在,当我在第一行中断时,
w
设置正确。我跳过,执行返回到调用函数:- (void) foo
{
int bar = [image width];
}
…现在是
bar
包含 NaN
.更新:嗯,明白了:
int foo = [image width]; // image is id, returns NaN
int bar = [(Image*) image width]; // correct value
image
声明为 id
,这就是这里的重点。有人可以解释一下吗?我有一种感觉,我说的不对 width
方法,但这里到底发生了什么?我总是尽可能严格地键入我的变量,但这里是 id
类型很方便。我不知道它会导致这样的错误。
最佳答案
那好吧。如果您对为什么会发生这种情况感兴趣,请参阅 Objective-C 编程指南,第 8 章,Return and Argument Types :
In general, methods in different classes that have the same selector (the same name) must also share the same return and argument types. This constraint is imposed by the compiler to allow dynamic binding. Because the class of a message receiver (and therefore class-specific details about the method it’s asked to perform), can’t be known at compile time, the compiler must treat all methods with the same name alike. When it prepares information on method return and argument types for the runtime system, it creates just one method description for each method selector.
However, when a message is sent to a statically typed object, the class of the receiver is known by the compiler. The compiler has access to class-specific information about the methods. Therefore, the message is freed from the restrictions on its return and argument types.
这是 bug report在 GCC bugzilla 中(以及相应的 blog post )。该行为不是错误,但也不是很友好,因为编译器不会警告您(至少在默认警告设置下不会)。
关于objective-c - Objective-C 中的动态类型和返回值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16310955/