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").