在Objective-C开发中从iOS迁移到Mac时,NSIntegers会给出类型匹配错误

时间:2012-02-01 03:44:36

标签: objective-c ios types type-conversion

我已经在iOS项目上工作了一段时间,我最近决定将代码移植到Mac项目中。因为我选择在我的代码中使用NSInteger,而NSInteger是一个依赖于环境的类型转换,这意味着我的变量在iOS和Mac应用程序中是不同的类型。

当我在Mac上运行测试套件时,我的所有STAssertEquals调用都会失败并显示错误“Type mismatch - ”,因为类型不匹配:

NSInteger foo = 1;
STAssertEquals(foo, 1, nil); // Test fails!!

对我的标量进行类型转换似乎有效,但这看起来非常混乱:

NSInteger foo = 1;
STAssertEquals(foo, (NSInteger)1, nil); // Succeeds, but is ugly!!

我在这里遗漏了什么吗?我开始怀疑使用NSIntegers的决定是一个糟糕的选择。

更新:或许this article是相关的。它似乎支持类型转换标量。

1 个答案:

答案 0 :(得分:5)

您对NSInteger的使用可能是正确的选择,但它确实会导致STAssertEquals出现一些问题。

如果两个对象具有不同的Objective-C type encodings

,则STAssertEquals会失败

单独的1将被C编译器解释为(signed int),其类型编码为“i”。

这些宏也会失败:

unsigned u = 1;
STAssertEquals(u, 1, nil); // Fails because u is type "I" (unsigned int) and 1 is type "i" (int)

char c = 1;
STAssertEquals(c, 1, nil); // Fails because c is type "c" (signed char) and 1 is type "i" (signed int)

要使编译器为1使用不同的类型,您可以为(unsigned int)添加后缀,例如1U,为(unsigned long)或{{1}添加1UL (长)。

NSInteger被定义为与指针大小相同,这取决于设备体系结构。在32位Mac OS X和iOS上,NSInteger是type(signed int)或“i”。在64位Mac OS X上,它是long类型或“q”。 (64位Mac OS X是LP64架构,这意味着 L ongs和 P ointers都 64 - 宽)

因此,STAssertEquals的左侧是“q”,而右侧是“i”,导致类型不匹配。

使用1L的解决方案似乎准确地表示了您想要的内容 - 针对值为1的NSInteger常量测试NSInteger变量。