我已经在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是相关的。它似乎支持类型转换标量。
答案 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变量。