NSInteger and NSUInteger in a mixed 64bit / 32bit environment

前端 未结 3 1964
礼貌的吻别
礼貌的吻别 2020-12-01 01:49

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

相关标签:
3条回答
  • 2020-12-01 02:13

    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
    
    0 讨论(0)
  • 2020-12-01 02:15

    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.

    0 讨论(0)
  • 2020-12-01 02:20

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

    0 讨论(0)
提交回复
热议问题