是否可以在 init 中编写非空注释?

Posted

技术标签:

【中文标题】是否可以在 init 中编写非空注释?【英文标题】:Is it possible to write nonnull-annotation in init? 【发布时间】:2015-10-01 12:51:17 【问题描述】:

现在在 Objective-c 中有两个新的注解:nonnullnullable。 我应该使用它们中的哪一个来指定 init 方法的返回类型?

- (instancetype)init 
    if (self = [super init]) 
        // ...
    

可为空的声音: 有一个“if”来检查 [super init] 返回的内容,并且不能保证它永远不会返回 nil。

非空的声音: 我不知道 init 返回 nil 的真实情况,我从不检查它。

【问题讨论】:

在某些情况下,初始化可能会失败,例如,您的对象是文件的接口,而该文件不存在或已损坏。在这种情况下,初始化可能会失败。 如果您的代码依赖于可能未指定的super 的实现,显然您不能使用nonnull 这取决于您继承的类及其内部逻辑。 Objectve-C 是一种非常灵活的语言。 objc 中的初始化程序与其他语言中的“构造函数”不同。初始化程序可能会因各种原因(如内部检查或其他原因)而失败。您甚至可以取消分配[super init] 给您的实例并创建另一个实例。您可能会发现阅读参考资料developer.apple.com/library/ios/documentation/General/… 很有用 @MikhailGasanov 例如[UIImage initWithData:] 说它返回“一个已初始化的 UIImage 对象,如果该方法无法从指定的数据初始化图像,则返回 nil。” 作为我的消息的补充:没有人禁止您将nonnull 放入初始化程序,但您必须注意[super init] 返回您nil 的情况。这可能涉及使用高级内存管理技术。 【参考方案1】:

对于任意类,the docs for -init 状态:

返回值:一个已初始化的对象,或 nil,如果由于某种不会导致异常的原因而无法创建对象。

随机类的init 方法可以返回nil。如果您要从该类的子类返回 [super init] 的结果,则返回可能是 nil。如果您的类返回可空的[super init] 的结果,则您的类应将其init 方法适当地注释为nullable

必须检查每个特定超类对象的init 实现,以确定子类对[super init] 的调用可以 还是不会依次返回nil

这表明你的方法的注解应该是nullable,除非你确认[super init]的结果不会nil

对于NSObject直接子类,具体来说:

NSObject 类中定义的 init() 方法不进行初始化;它只是返回自我。在可空性方面,调用者可以假设 init() 的 NSObject 实现不返回 nil。

因此对于直接从NSObject 继承的类,-init 可以标记为nonnull

如果你的班级返回 nil:

[super init] 的结果可能是nonnull,但您的类对init 的实现返回nil 以响应某些其他条件。

- (instancetype)init 
    if (self = [super init])  // nonnull

        if (someFailureCondition) 
            return nil; // nullable
        

    

    return self;

在这种情况下,您的实现当然应该注释为nullable

【讨论】:

上述来自the docs 的引用文本似乎通常指的是init 方法,而不是NSObject 的init,特别是文档继续声明:“init 方法定义在NSObject 类没有初始化;它只是返回 self"。所以对于NSObject 本身,这表明init 不会返回nil【参考方案2】:

您可以假设[[NSObject alloc] init] 永远不会失败。以下是文档的实际内容:

NSObject类中定义的init方法不做初始化;它只是返回自我。在可空性方面,调用者可以假设 init 的 NSObject 实现不返回 nil。

参考:https://developer.apple.com/reference/objectivec/nsobject/1418641-init?language=objc

【讨论】:

以上是关于是否可以在 init 中编写非空注释?的主要内容,如果未能解决你的问题,请参考以下文章

是否必须为 __init__ 做注释?

在 javadoc 注释中编写代码 [重复]

是否可以在 shell 脚本中的多行命令中包含内联注释? [复制]

我们如何在jenkins上强制为团队项目编写java注释?

测试浏览器是否支持JavaScript脚本

Grails bindData由注释排除