是否可以在 init 中编写 nonnull-annotation?

Is it possible to write nonnull-annotation in init?

现在 objective-c 中有两个新注释:nonnullnullable.
return init 方法的类型规范我应该使用它们中的哪一个?

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

可空的声音:
有一个 "if" 来检查 [super init] returns 并且不能保证它永远不会 returns nil.

nonnull 的语音:
当 init returns nil 并且我从不检查它时,我不知道真实的情况。

对于任意classthe docs for -init状态:

Return Value: An initialized object, or nil if an object could not be created for some reason that would not result in an exception.

随机class的init方法可以returnnil。如果您 return 从那个 class 的子 class 得到 [super init] 的结果,那么 return 有可能是 nil.如果 return 是可空 [super init].

的结果,您的 class 应该适当地将其 init 方法注释为 nullable

必须检查每个特定的超级class对象的init实现以确定子class对[super init]的调用是否可以或不会依次returnnil

这表明您的方法的注释应该是 nullable,除非您已经确认 [super init] 的结果 而不是 nil ].

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

The init() method defined in the NSObject class does no initialization; it simply returns self. In terms of nullability, callers can assume that the NSObject implementation of init() does not return nil.

因此对于直接继承自NSObject的classes,-init可以标记为nonnull.

如果你的class return没有:

有可能 [super init] 的结果是 nonnull,但是你的 class 对 init return 的实现 nil响应其他一些条件。

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

        if (someFailureCondition) {
            return nil; // nullable
        }

    }

    return self;
}

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

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

The init method defined in the NSObject class does no initialization; it simply returns self. In terms of nullability, callers can assume that the NSObject implemetation of init does not return nil.

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