2017-09-12 118 views
3

为什么我们无法在32位设备(iPhone5,iPhone4s或其模拟器)中使用“%zd”预期格式化字符串?“NSString stringWithFormat:”与“%zd”在32位设备中的好奇行为

int64_t test1 = 11111111; 
int64_t test2 = 22222222; 
int64_t test3 = 33333333; 
int64_t test4 = 44444444; 
NSString *testStr = [NSString stringWithFormat:@"\"%zd %zd %zd %zd\"", test1, test2, test3, test4]; 
NSLog(@"testStr: %@", testStr); 

NSInteger test5 = 55555555; 
NSInteger test6 = 66666666; 
NSInteger test7 = 77777777; 
NSInteger test8 = 88888888; 
testStr = [NSString stringWithFormat:@"\"%zd %zd %zd %zd\"", test5, test6, test7, test8]; 
NSLog(@"testStr: %@", testStr); 

日志是:

2017-09-12 05:53:59.462: testStr:"11111111 0 22222222 0" 
2017-09-12 05:53:59.465: testStr:"55555555 66666666 77777777 88888888" 

回答

3

注:回答刚才输入的平板电脑,而不是测试你的样品,所以这是一个猜测。

格式%zd适用于size_t类型的值,而不是64位值。

尝试使用%lld代替int64_t值,long long在32位和64位iOS版本上均为64位。

对于NSInteger尝试%ld和铸铁的参数long,这是因为NSInteger的大小取决于平台。

HTH

+0

想想你的答复。 对不起,反应慢。 我知道你在说什么,而你的回答是该死的。但我仍然不知道为什么这些行为如此神秘(先看看)。 – Ziiip

+1

当参数传递给一个*变量参数*函数/方法时,例如'stringWithFormat:',每个参数值的* bytes *被连续放置在堆栈上。变量'test1'是64位,所以8个字节放在堆栈中,后面跟着8个字节'test2'等。在32位'%zd'格式化一个32位值,所以对于格式字符串中每个出现的'%zd',使用4个字节。当十进制值“11111111”被写为64位二进制数时,前32位全为“0”。所以'test1'的8个字节被格式化为两个4字节值,其中第二个是'0'。 – CRD

+0

听起来很合理!非常感谢你。而且,我在哪里可以学到这一点?这是我不知道的有趣知识。 – Ziiip