NSNotFound 的可用性如何?

What is the availability of NSNotFound?

NSNotFound 的 Xcode 文档非常混乱:

它说 "Available in iOS 2.0 through 8.4" 和 "Availability: iOS 8.1 to 8.0"。那么... 8.0之前可以使用吗?还是9.0+?另外,如果是的话,这是怎么回事?

我意识到 NSNotFound 是一个静态常量,因此 OS 设备具有什么无关紧要,因为值 不应该 编译后变化。

为了证实这一点,我制作了最简单的文件并查看了它的编译程序集(没有优化):

左:原始C源代码。 右: LLVM 汇编输出。

如您所见,NSNotFound 被替换为其绝对值,在本例中为 0x7fffffffffffffff,因为这是 64 位编译。对于 32 位编译,它将是 0x7fffffff.

这太棒了。这意味着,只要它编译,它就可以工作(假设 Apple 从不更改 NSNotFound 的值)!

虽然这不能解释奇怪的文档,但它确实提供了一些保证,它应该适用于所有版本的 iOS。

在这里插入availabilityOfNSNotFound == NSNotFound笑话。


在 Apple 推出强制性 64 位设备支持(iOS 8.4 SDK?)的某个时候,NSNotFound 的声明更改为:

enum {NSNotFound = NSIntegerMax};

static const NSInteger NSNotFound = NSIntegerMax;

您可以在 <Foundation/NSObjCRuntime.h> 中验证这一点。

文档从未更改,因此 SDK 中不再提供 enum NSNotFound。但从 iOS 9 及更高版本开始,static const NSInteger NSNotFound 可用。

尽管我无法回答 NSNotFound 的真实可用性,因为我不为 Apple 工作(作为开发人员,我认为在 2.0 之后的所有 iOS 版本中使用是安全的,否则许多 Foundation 类 会崩溃,因为它们可以 return NSNotFound),您可以检查 NSNotFound 的内存位置是否为 NULL:

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wtautological-compare"
BOOL found = (&NSNotFound != NULL);
#pragma clang diagnostic pop
if (found) {
    NSLog(@"meh");
}