_Nullable 和 _Nonnull 对 Swift 互操作以外的任何东西有用吗?

Are _Nullable and _Nonnull useful for anything other than Swift interop?

如果 Objective-C 编译器认为您可能将 nil 传递给标有 _Nonnull 的参数,它是否真的会警告您?

或者它只是提示任何工具在 Swift 和 Objective-C 之间转换以更好地处理 Swift 可选值?

就其本身而言,只有在极其微不足道的情况下才会出现警告:当您将 nil 传递给接受 _Nonnull 值的函数时。

NSObject* _Nonnull test(NSObject* _Nonnull) {
    test(nil);  // warning

    NSObject* _Nullable f = nil;
    test(f); // no warning (passing _Nullable to _Nonnull), only warn in static analysis

    NSObject* _Nonnull g = [[NSObject alloc] init];
    g = nil; // no warning (!) (assigning nil to _Nonnull)

    if (g != nil) {  // no warning (unnecessary '!= nil' comparison)
        test(g);
    }

    return nil; // no warning (returning nil to _Nonnull)
}

(有一个-Wnullable-to-nonnull-conversion flag但是好像对上面的代码没有任何影响。)

As documented,这三个属性不会改变代码的行为:

… Note that, unlike the declaration attribute nonnull, the presence of _Nonnull does not imply that passing null is undefined behavior: fetch is free to consider null undefined behavior or (perhaps for backward-compatibility reasons) defensively handle null.

除了编译器之外,它还会帮助静态分析器,但 clang 的静态分析器同样只会捕获它确定要将 nil 分配给 _Nonnull 的琐碎情况(即上面的 test(f) 示例)。

尽管如此,将指针_Nonnull/_Nullable标记为

仍然有用
  1. 文档;
  2. 允许 Swift 开发人员更好地使用您的库;
  3. 如果你不添加这些注释,编译器会到处发出警告