用可空性注解装饰 ObjC 代码时,你还需要做定义,还是只做声明? 可读性与生产力

问题描述

我们正在准备一堆或 ObjC 代码供 Swift 使用,这当然需要可空性注释。现在我的理解是那些可空性注释只需要在声明站点,而不是在定义上。这意味着对于声明在头文件中而定义在 m/mm 文件中的情况,您不需要将它们添加到后者中。

例如...

Foo.h:

- (nullable Foo *)getFooWithKey:(Nsstring *_Nonnull)key;

Foo.mm:

- (Foo *)subtree:(Nsstring *)key
{
  // Some implementation here...
}

现在我的一些在 ObjC 方面有更多经验的同事说他们必须在两个地方都去,这意味着 mm 文件实际上必须是这个......

Foo.mm:

- (nullable Foo *)subtree:(Nsstring *_Nonnull)key
{
  // Some implementation here...
}

当我问为什么时,他们说他们“匹配”。然而,当我们从 m/mm 文件删除它们时,它们似乎仍然可以在没有它们的情况下在 Swift 中正常导入,因为 Swift 只查看标题

也就是说,我不确定在这两个地方是否还有其他需要考虑的事情,我们只是没有测试,所以我不能说这是确定的,只是我们的测试有效。

>

可读性与生产力

现在通常,即使后者实际上没有做任何事情,如果它有助于提高可读性,那就足以说“把它放在两个地方”。但是,在我们的特定情况下,我们可能有数万个 API 需要更新,因此消除大量额外工作对每个人来说都是一个巨大的胜利。此外,它还使编写代码模块变得更容易。

我在 Apple's documentation 中找到的关于此的最接近的是这两个摘录(重点是我的)...

但是,在一般情况下,有一种更好的方式来编写这些注释:方法声明中,您可以使用非下划线形式 nullablenonnull 紧跟在左括号之后,只要类型是简单对象或块指针。

非下划线形式比下划线形式更好,但您仍然需要将它们应用于标题中的每种类型。为了使这项工作更轻松并让您的标题更清晰,您需要使用经过审核的区域。

虽然不是绝对的。第一个可能是将其称为“特定于声明”的“更好的方式”,但它并没有说注释通常只用于那里。后者也说非下划线的注释可以在标头中使用,但同样,并没有说一般情况下可空性注释只能出现在标头中,只有被审计的区域才会出现。

也就是说,有谁知道 Apple 会在哪里澄清这一点,或者可以分享任何其他内容让我们知道可以在定义/实现中跳过它们吗?

解决方法

只需要对声明进行注释。对于方法,这意味着带有接口的头文件。