The reason for this is the change in word length when 5s came out. In other words, 5 or more iPhones have a 64-bit processor, and all previous iPhones have a 32-bit processor.
Here are actually typedefs for NSUInteger
#if __LP64__ || (TARGET_OS_EMBEDDED && !TARGET_OS_IPHONE) || TARGET_OS_WIN32 || NS_BUILD_32_LIKE_64 typedef long NSInteger; typedef unsigned long NSUInteger; #else typedef int NSInteger; typedef unsigned int NSUInteger; #endif
You can see that for a 32-bit processor, NSUInteger
explicitly defined as unsigned int
, while for a 64-bit processor, NSUInteger
explicitly protected as unsigned long
.
So, looking at this code ...
NSUInteger bob = 12234; NSLog(@"bob %lu", bob);
For 4s, this NSLog
has a mismatch, since NSUInteger
explicitly defined as unsigned int
, and the %lu
format specifier is unsigned long
. This very apparent mismatch is the reason that a warning exists for 32-bit processors. There is no mismatch for a 64-bit processor and therefore no warnings.
The proposed fix in the warning suggests that you intended to use an unsigned long
. However, this is an alternative solution.
NSUInteger bob = 12234; #if __LP64__ || (TARGET_OS_EMBEDDED && !TARGET_OS_IPHONE) || TARGET_OS_WIN32 || NS_BUILD_32_LIKE_64 NSLog(@"bob %lu", bob); #else NSLog(@"bob %u", bob); #endif
The bottom line is that you are trying to warn of a non-compliance when there is no non-compliance, which is neither suitable nor possible.
EDIT:
This is not a case of a mismatch error that does not appear as a warning / error. There is literally no discrepancy. The only way to show this error is actually a mismatch. There will only be a mismatch if you build against architectures for which the NSUInteger
definition will create a mismatch in the specific code you specify. There is a standard way to do this: set only "Build Active Architecture Only" to NO for all your circuits .