如何使我的iPhone应用程序同时在64位和32位上运行?
当我尝试在64位模式下运行时,我得到的确切错误是如何使我的iPhone应用程序同时在64位和32位上运行?,iphone,objective-c,xcode,64-bit,32bit-64bit,Iphone,Objective C,Xcode,64 Bit,32bit 64bit,当我尝试在64位模式下运行时,我得到的确切错误是格式指定类型为“int”,但参数的类型为“long” 我可以通过将%d更改为%ld来修复此错误,但是,当我在32位(正常)模式下运行应用程序时,会出现一个错误,错误是:格式指定类型“long”,但参数的类型为“int” 如何解释64位和32位?是否存在我创建的if(条件) - (void)pickerView:(UIPickerView *)pickerView didSelectRow: (NSInteger)row inComponent:(N
格式指定类型为“int”,但参数的类型为“long”
我可以通过将%d
更改为%ld
来修复此错误,但是,当我在32位(正常)模式下运行应用程序时,会出现一个错误,错误是:格式指定类型“long”,但参数的类型为“int”
如何解释64位和32位?是否存在我创建的if(条件)
- (void)pickerView:(UIPickerView *)pickerView didSelectRow: (NSInteger)row inComponent:(NSInteger)component {
// Handle the selection
if(pickerView.tag == 1){
start = row+1;
[startButton setTitle:[NSString stringWithFormat:@"%d. %@", row+1, [stops objectForKey:[NSString stringWithFormat:@"%d", row+1]]] forState:UIControlStateNormal];
}else if (pickerView.tag == 2){
stop = row+1;
[endButton setTitle:[NSString stringWithFormat:@"%d. %@", row+1, [stops objectForKey:[NSString stringWithFormat:@"%d", row+1]]] forState:UIControlStateNormal];
}
}
如果您右键单击
NSInteger
,然后单击“转到定义”,您可以确切地看到它是如何定义的,并将其作为一个框架,为%d
/%ld
设置一个类似的\define
,以匹配您的NSInteger
这就是
NSInteger
的工作原理。你可以做类似的事情:
#if __LP64__
#define FS_NSInt ld
#else
#define FS_NSInt d
#endif
然后只需使用
FS\u NSInt
作为NSInteger
s的格式说明。(将%
仍放在它前面)不要使用NSInteger
或NSInteger
作为格式参数。而是将其强制转换(例如,转换为long
:
[NSString stringWithFormat:@"%lld", (long long)row+1]
从:
类型说明符:
通常,在32位代码中,使用%d说明符格式化int
函数中的值,如printf、NSAssert和NSLog,以及
方法,例如stringWithFormat:,但使用NSInteger,它位于64位
架构的大小与长度相同,您需要使用%ld
说明符。除非您构建的是像64位一样的32位,否则
说明符以32位模式生成编译器警告
问题是,您可以将值强制转换为long或unsigned long,如下所示
适当。例如:
解决这个问题的一种方法是使用stdint.h中的类型:int8\u t,uint8\u t,int16\u t,uint16\u t,int32\u t,uint32\u t,int64\u t,uint64\u t我应该将它们转换为什么?我该如何选择?long是最佳选择吗?long
是一个安全的选择。clang实际上有一个警告,建议将NSInteger
转换为long。如果你不需要将其转换为long
,你可能在本例中,首先使用int
而不是NSInteger
很好。最后一个问题……假设我决定让我的应用程序只运行32位,因为它实际上不需要更大的64位变量大小……新iPhone 5S会将我的应用程序降级到32位吗,还是不会运行应用程序?是的,对bo来说问题。但不管怎样,你只会把它抛给一个(long-long)
暂时。所以我应该更改typedef int NSInteger;
?不,你不能用C重新定义typedef。绝对不能。NSInteger
是一个条件typedef
,在32位系统上使用int
,在64位系统上使用long
。你可以查看NSInteger
的typedef
>(我现在不在Mac电脑上,否则我会为你写)并以此为框架,为格式说明符编写类似的条件。请注意,在32位和64位处理器上,long-long和unsigned-long都是64位的。long-long不会比常规int占用更多空间吗?这对仅运行32位的iPhone实用吗?它将占用64位(8字节)但是,除非你有几千个。注意,这不是一个答案,只是信息,请参阅下面我的答案。不会抛出一个长的,比int占用更多的空间吗?如果iPhone只有32位,那么仅仅有一个int不是更好吗?我有点困惑,因为这似乎是一个负面的好处…我一直被认为使用变量siz与你的需要相匹配,a long大于我的需要。这有意义吗?如果你从来都不需要大于int
所能容纳的数字,你应该只使用int
而不是NSInteger
。许多古老的“真理”规则1:过早优化是万恶之源。故事:我得到了一份工作,因为当被问及优化问题时,我首先回答了测量。我想我想说的是,用户担心在32位系统上通过强制转换为长的而浪费RAM,但不担心浪费相同的RAM使用NSInteger
(64位上的长
)在64位系统上使用RAM。如果他关心并且不需要一个int
无法容纳的数字,他可以使用int
并避免原始问题中的问题。或者他可以忽略大小/性能问题,除非存在直接和证明相关的性能问题。
[NSString stringWithFormat:@"%lld", (long long)row+1]
NSInteger i = 34;
printf("%ld\n", (long)i);