【问题标题】:What is the availability of NSNotFound?NSNotFound 的可用性是什么?
【发布时间】:2015-10-29 16:16:23
【问题描述】:

NSNotFound 的 Xcode 内文档非常令人困惑:

它显示“在 iOS 2.0 到 8.4 中可用”和“可用性:iOS 8.1 到 8.0”。那么... 8.0 之前可以使用吗?还是在 9.0+ 中?另外,如果是的话,这里发生了什么?

【问题讨论】:

  • 发现了吗?或者只是尝试看看它在不同版本上的表现如何?当前文档现在显示Availability (8.0 to 8.0)
  • @Alex 我没有。它似乎至少在 iOS 7.2 到 9.2.1 中运行良好,因为这是我们的应用支持的版本。
  • 从 iOS 7.0 到 9.2.1 对我来说似乎也可以正常工作。很奇怪。
  • 我建议向Apple 提交文档错误。

标签: ios foundation code-documentation


【解决方案1】:

在此处插入 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 NSIntegerNSNotFound 可用。

虽然我无法回答 NSNotFound 的真实可用性,因为我不为 Apple 工作(作为开发人员,我认为在 2.0 之后的所有 iOS 版本中使用它是安全的,否则很多 Foundation 类会中断,因为它们可以返回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");
}

【讨论】:

    【解决方案2】:

    我意识到NSNotFound 是一个静态常量,因此设备具有什么操作系统并不重要,因为编译后值不应该改变。

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

    左:原始C源代码。 右: LLVM 程序集输出。

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

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

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

    【讨论】:

    • 你真的不应该使用硬编码值而不是常量。常数这样暴露是有原因的!此外,该值被分配给NSIntegerMax,它扩展为LONG_MAX,这可能与平台有关。
    • @JAL 我想你误会了我。我正在使用常量!左窗格是 C 代码,右窗格是编译器的汇编输出。
    • 我没有误会你。我只是说使用任何一个常量都不安全。
    • @JAL 但是你说“你真的不应该使用硬编码值而不是常量。”我不是;我正在使用常量。
    • 我明白了,你指的是编译后的值。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多