I have a fair amount of string format specifiers in NSLog / NSAssert etc. calls which use %d
and %u
with NSInteger (= int on 32bit)
an
I think the safest way is to box them into NSNumber
instances.
NSLog(@"Number is %@", @(number)); // use the highest level of abstraction
This boxing doesn't usually have to create a new object thanks to tagged pointer magic.
If you really don't want to use NSNumber
, you can cast primitive types manually, as others suggested:
NSLog(@"Number is %ld", (long)number); // works the same on 32-bit and 64-bit
You can also use %zd
(NSInteger
) and %tu
(NSUInteger
) when logging to the console.
NSInteger integer = 1;
NSLog(@"first number: %zd", integer);
NSUInteger uinteger = 1;
NSLog(@"second number: %tu", uinteger);
Also to be found here.
No, (unfortunately) there is no printf format that directly corresponds to NS(U)Integer
.
So for architecture independent code, you have to convert everything to the "long"
variant (as the Xcode "Fix-it" suggests):
NSInteger i = ...;
NSLog(@"%ld", (long)i);
The only alternative that I know of is from Foundation types when compiling for arm64 and 32-bit architecture:
// 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);
using preprocessor macros (but even the author of that answer calls it a "admittedly awful approach").