Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective-C中的动态类型和返回值_Objective C_Dynamic Typing - Fatal编程技术网

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

Objective-C中的动态类型和返回值,objective-c,dynamic-typing,Objective C,Dynamic Typing,我遇到了一种我无法理解的非常奇怪的行为。我有一个Texture类,其contentWidth属性的类型为int。该类被包装在一个图像类中,该类具有类型为int的宽度属性。图像的宽度仅作为底层纹理的内容宽度计算: - (int) width { return texture.contentWidth; } 现在,图像由一个按钮类使用(通过合成,而不是继承),该类希望读取图像大小: // image is of type ‘id’ int width = [image width]; in

我遇到了一种我无法理解的非常奇怪的行为。我有一个
Texture
类,其
contentWidth
属性的类型为
int
。该类被包装在一个
图像
类中,该类具有类型为
int
宽度
属性。
图像的
宽度
仅作为底层纹理的
内容宽度
计算:

- (int) width
{
    return texture.contentWidth;
}
现在,
图像
由一个
按钮
类使用(通过合成,而不是继承),该类希望读取图像大小:

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


更新:我在
Image
类中扩展了访问器,以查看问题的根源:

- (int) width
{
    const int w = texture.contentWidth;
    return w;
}
现在,当我在第一行中断时,
w
设置正确。I跳过,执行返回到调用函数:

- (void) foo
{
    int bar = [image width];
}
…现在,
包含
NaN


更新:嗯,明白了:

int foo = [image width]; // image is id, returns NaN
int bar = [(Image*) image width]; // correct value

图像
声明为
id
,这就是此处的要点。有人能解释一下吗?我感觉我没有调用正确的
width
方法,但这里到底发生了什么?我总是尽可能严格地键入变量,但这里的
id
类型很方便。我不知道它会导致这样的错误。

您的访问者不应该是:

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

纹理是实例变量吗?如果是的话,您是否使用super在init方法或包装器类中对其进行了初始化?

哦。如果您对这种情况发生的原因感兴趣,请参阅Objective-C编程指南第8章:

一般来说,不同的方法 具有相同选择器的类 (同名)也必须共享 返回和参数类型相同。这 约束是由编译器施加的 允许动态绑定。因为 消息接收器的类别(和 因此,关于 要求它执行的方法), 在编译时无法知道,则 编译器必须使用 名字一样。当它准备好的时候 有关方法返回和返回的信息 运行时系统的参数类型, 它只创建一个方法描述 对于每个方法选择器

但是,当消息发送到 静态类型对象,是 编译器知道接收器。 编译器可以访问 类的特定信息 方法。因此,信息是 摆脱了对它的限制 返回和参数类型


下面是GCC bugzilla中的一个(以及相应的一个)。该行为不是一个bug,但也不是很友好,因为编译器不会警告您(至少不会使用默认的警告设置)。

您是否在纹理类中实现了contentWidth访问器?宽度和高度访问器之间的区别是什么?高度访问器是如何在图像中实现的?@Tim:没有区别,“高度”访问器看起来完全一样。当然,除了名称之外:)@Perspx:Yes,否则编译器会在Image类的“width”访问器中抱怨。两者是等效的-Objective-C将在编译期间将点访问器语法转换为传递的消息。从“良好实践”的角度来看,这是个好主意。。。在这种情况下,我会确保您的实例已正确初始化。我刚刚覆盖了纹理类上的“description”方法,并在那里记录了维度,它们都很好。