Objective-C中的动态类型和返回值

时间:2009-07-11 08:44:25

标签: objective-c dynamic-typing

我遇到了一种我无法理解的非常奇怪的行为。我有一个Texture类,其contentWidth属性类型为int。此类包含在Image类中,该类具有类型为width的{​​{1}}属性。 int的{​​{1}}仅计算为基础纹理的width

Image

现在contentWidth- (int) width { return texture.contentWidth; } 类(通过合成,而不是继承)用于想要读取图像大小的内容:

Image

问题是Button变量设置得很好,而// image is of type ‘id’ int width = [image width]; int height = [image height]; 变量包含height(-2147483648)。我检查了尺寸 - 它们大约是200×100左右,远不到width极限。此外,Xcode调试器工具提示正确显示NaN中的两个属性,只有在宽度通过两个访问器后,数字才会出现乱码。对象未释放。我错过了什么?


更新:我已在int类中扩展了访问者,以查看问题的来源:

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类型很方便。我不知道它会导致这样的错误。

2 个答案:

答案 0 :(得分:5)

好吧,好吧。如果您对发生这种情况的原因感兴趣,请参阅Objective-C编程指南,第8章,Return and Argument Types

  

一般来说,方法不同   具有相同选择器的类   (同名)也必须分享   相同的返回和参数类型。这个   约束由编译器强加   允许动态绑定。因为   消息接收器的类(和   因此,特定于类的细节   它被要求执行的方法),   在编译时无法知道的   编译器必须处理所有方法   同名的人。准备的时候   方法返回和信息   运行时系统的参数类型,   它只创建一个方法描述   对于每个方法选择器。

     

然而,当一条消息被发送到   静态类型对象,类   接收器是编译器已知的。   编译器可以访问   有关的特定类别信息   方法。因此,消息是   摆脱对它的限制   返回和参数类型。

这是GCC bugzilla中的bug report(以及相应的blog post)。行为不是错误,但它也不是很友好,因为编译器不会警告你(至少没有默认的警告设置)。

答案 1 :(得分:1)

你的访问者不应该是:

- (int) width
{
    return [texture contentWidth];
}

纹理是实例变量吗?如果是,你是否使用init方法或你的包装类来初始化它?