现在在Objective-C中有两个新的注释:nonnull和nullable。
我应该在init方法的返回类型说明中使用哪一个?
- (instancetype)init {
if (self = [super init]) {
// ...
}
}
关于可空的参数的说明:
有一个“if”语句来检查 [super init] 的返回值,不能保证它永远不会返回 nil。
关于非空的参数的说明:
我不知道什么情况下 init 会返回 nil,也从未检查过。
现在在Objective-C中有两个新的注释:nonnull和nullable。
我应该在init方法的返回类型说明中使用哪一个?
- (instancetype)init {
if (self = [super init]) {
// ...
}
}
关于可空的参数的说明:
有一个“if”语句来检查 [super init] 的返回值,不能保证它永远不会返回 nil。
关于非空的参数的说明:
我不知道什么情况下 init 会返回 nil,也从未检查过。
返回值:如果无法创建对象但不会导致异常,则为已初始化的对象或nil。
一个随机类的init
方法可以返回nil
。如果你从该类的子类返回[super init]
的结果,有可能返回nil
。如果init
返回可空的[super init]
的结果,则应适当注释其init
方法为nullable
。
必须检查每个特定的超类对象的init
实现,以确定子类调用[super init]
是否可能或不会反过来返回nil
。
这表明,除非已经确认[super init]
的结果不会是nil
,否则你的方法声明应为nullable
。
NSObject
的直接子类:
NSObject
类中定义的init()
方法不执行任何初始化;它只是返回self。在空值方面,调用者可以假定NSObject
实现的init()
不会返回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
。init
方法,而不是特指NSObject
类的init
方法。因为文档接着说明:"在NSObject
类中定义的init
方法不会进行任何初始化操作,它只是返回self
"。所以就NSObject
本身而言,这意味着init
方法不会返回nil
。 - HexAndBugs[[NSObject alloc] init]
永远不会失败。文档实际上是这样描述的:
参考: https://developer.apple.com/reference/objectivec/nsobject/1418641-init?language=objc在 NSObject 类中定义的 init 方法不执行任何初始化操作,只是返回 self。在 nullability 方面,调用者可以假定 NSObject 的 init 实现不会返回 nil。
super
实现,显然就不能放置nonnull
。 - Max Komarychev[super init]
提供的实例并创建另一个实例。您可能会发现阅读参考文献 https://developer.apple.com/library/ios/documentation/General/Conceptual/CocoaEncyclopedia/Initialization/Initialization.html 很有用。 - Max Komarychev[UIImage initWithData:]
方法返回“已初始化的UIImage对象,如果该方法无法从指定的数据初始化图像,则返回nil。”@MikhailGasanov - Max Komarychevnonnull
,但是您必须意识到当[super init]
返回nil
时的情况。这可能涉及使用高级内存管理技术。 - Max Komarychev