28

私は NSLog / NSAssert などの呼び出しでかなりの量の文字列形式指定子を持っ%d%uNSInteger (= int on 32bit)ますNSUInteger (= unsigned int on 32bit)

アプリを 64 ビットに変換すると、(もちろん) 警告が表示さ%ld %luれます。longunsigned long

もちろん、フォーマット指定子を単純に変換すると、32 ビット ビルドで逆の警告が発生します。
したがって、警告が発生しない唯一の解決策は、64 ビット指定子を使用し、32 ビット ビルドで警告が発生するすべての場所で 64 ビット値型にキャストすることです。

しかし、キャストせずに両方のアーキテクチャで機能するNSIntegerand型専用のフォーマット指定子があるのではないかと思っていましたか?NSUInteger

4

3 に答える 3

61

NSNumber最も安全な方法は、それらをインスタンスにボックス化することだと思います。

NSLog(@"Number is %@", @(number)); // use the highest level of abstraction

このボクシングでは、タグ付きポインターマジックのおかげで、通常は新しいオブジェクトを作成する必要はありません。

本当に使用したくない場合はNSNumber、他の人が示唆しているように、プリミティブ型を手動でキャストできます。

NSLog(@"Number is %ld", (long)number); // works the same on 32-bit and 64-bit
于 2013-12-03T21:30:50.750 に答える
4

いいえ、(残念ながら) に直接対応する printf 形式はありませんNS(U)Integer。したがって、アーキテクチャに依存しないコードの場合は、すべてを「長い」バリアントに変換する必要があります (Xcode の「Fix-it」が示唆するように)。

NSInteger i = ...;
NSLog(@"%ld", (long)i);

私が知っている唯一の代替手段は、arm64 および 32 ビット アーキテクチャ用にコンパイルするときの Foundation 型からのものです。

// In the precompiled header file:
#if __LP64__
#define NSI "ld"
#define NSU "lu"
#else
#define NSI "d"
#define NSU "u"
#endif

NSInteger i = ...;
NSLog(@"i=%"NSI, i);

プリプロセッサマクロを使用します(ただし、その回答の作成者でさえ、それを「明らかにひどいアプローチ」と呼んでいます)。

于 2013-12-03T16:08:09.520 に答える