This in-Xcode documentation for NSNotFound
is quite confusing:
It says \"Available in iOS 2.0 through 8.4\" and \"Availability: iOS 8.1 to 8.0\
Insert availabilityOfNSNotFound == NSNotFound
joke here.
At some point when Apple was pushing mandatory 64-bit device support (iOS 8.4 SDK?), the declaration of NSNotFound
was changed from:
enum {NSNotFound = NSIntegerMax};
to
static const NSInteger NSNotFound = NSIntegerMax;
You can verify this in <Foundation/NSObjCRuntime.h>
.
The documentation was never changed, so the availability of the enum
NSNotFound
is no longer in the SDK. But as of iOS 9 and above, the static const NSInteger
NSNotFound
is available.
Although I cannot answer the true availability of NSNotFound
since I don't work for Apple (as a developer I think it's safe to use in all iOS versions since 2.0, or else a lot of Foundation classes would break since they can return NSNotFound
), you can check to see if the memory location for NSNotFound
is NULL:
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wtautological-compare"
BOOL found = (&NSNotFound != NULL);
#pragma clang diagnostic pop
if (found) {
NSLog(@"meh");
}
I realized that NSNotFound
is a static constant, and so it shouldn't matter what OS the device has, as the value shouldn't change after compilation.
To confirm this, I made the simplest file I could and looked at its compiled assembly (without optimizations):
Left: original C source code. Right: LLVM assembly output.
As you can see, NSNotFound
is replaced with its absolute value, in this case 0x7fffffffffffffff
since this is a 64-bit compilation. For 32-bit compilations, it would be 0x7fffffff
.
This is awesome. It means that, as long as it compiles, it will work (assuming Apple never changes the value of NSNotFound
)!
While this doesn't explain the strange documentation, it does provide some reassurance that it should work on all versions of iOS.