NSLog/NSAssertなどの呼び出しで、かなりの量の文字列フォーマット指定子があります。これらは、それぞれNSInteger (= int on 32bit)
およびNSUInteger (= unsigned int on 32bit)
タイプで%d
および%u
を使用します。
アプリを64ビットに変換すると、long
および%ld %lu
タイプになったものに対してunsigned long
が期待されるため、これは警告を出します(もちろん)。
もちろん、フォーマット指定子を変換するだけで、32ビットビルドで逆の警告が発生します。
したがって、警告なしになると私が思う唯一の解決策は、64ビット指定子を使用し、32ビットビルドで警告が出されるすべての場所で64ビット値型にキャストすることです。
しかし、おそらくNSInteger
およびNSUInteger
タイプ専用のフォーマット指定子があり、キャストせずに両方のアーキテクチャで機能するかどうか疑問に思っていましたか?
私はそれらをNSNumber
インスタンスにボックス化するのが最も安全な方法だと思います。
NSLog(@"Number is %@", @(number)); // use the highest level of abstraction
タグ付きポインタ マジックのおかげで、このボクシングは通常、新しいオブジェクトを作成する必要はありません。
reallyがNSNumber
を使用したくない場合は、他の人が提案したように、プリミティブ型を手動でキャストできます。
NSLog(@"Number is %ld", (long)number); // works the same on 32-bit and 64-bit
コンソールにログインするときに、%zd
(NSInteger
)および%tu
(NSUInteger
)を使用することもできます。
NSInteger integer = 1;
NSLog(@"first number: %zd", integer);
NSUInteger uinteger = 1;
NSLog(@"second number: %tu", uinteger);
いいえ、(残念ながら)NS(U)Integer
に直接対応するprintf形式はありません。したがって、アーキテクチャに依存しないコードの場合、すべてを「長い」バリアントに変換する必要があります(Xcodeの「Fix-it」が示唆するように)。
NSInteger i = ...;
NSLog(@"%ld", (long)i);
私が知っている唯一の選択肢は arm64および32ビットアーキテクチャ用にコンパイルするときの基礎タイプ からのものです。
// 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);
プリプロセッサマクロを使用する(ただし、その回答の作成者でさえ、「明らかにひどいアプローチ」と呼んでいます)。