我想为NSObject子类提供一个可用的初始化程序,以便在没有参数的情况下进行初始化。我的总体目标是返回nil这个类在小于8.0的OS版本上初始化。
我的尝试如下:
class MyObject: NSObject {
override init?() {
super.init()
if floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_7_1 {
return nil
}
}
}
但是,此代码会导致以下编译器错误。
Failable initializer 'init()' cannot override a non-failable initializer
是否可以覆盖init()以在子类中提供可用的实现?或者有更好的方法来实现这一目标吗?
答案 0 :(得分:4)
由于你是NSObject的子类,你不能拥有一个可用的无参数初始化器,因为NSObject没有参数初始化器是不可用的。
您可以创建一个类工厂方法,该方法根据iOS版本
返回实例或nil答案 1 :(得分:4)
鉴于:
您可以使用不可用的初始化程序覆盖可用的初始化程序,但不能反过来。
和
可用的初始化程序也可以委托给不可用的初始化程序。如果您需要将潜在的故障状态添加到现有的初始化过程中,请使用此方法,否则将无法失败。
并且考虑到NSObject
没有无参数的可用初始值设定项,那么不能,您不能使用可用的初始化程序覆盖不可用的初始值设定项。
我看到的唯一选择是使用虚拟参数创建初始化程序,例如:
class MyObject: NSObject {
init?(_ ignore: Bool) {
super.init()
if floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_7_1 {
return nil
}
}
}
然后将其用作:
var myObj = MyObject(true)
或
var myObj = MyObject(false)
更有趣的是,为虚拟参数分配默认值似乎很好地完成了这项工作:
class MyObject: NSObject {
init?(_ ignore: Bool = false) {
super.init()
if floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_7_1 {
return nil
}
}
}
var myObj = MyObject()
答案 2 :(得分:0)
如果您不想传递'dummy'参数,则可以传递inout
错误。这样,您就可以避免使用虚拟参数污染代码,并且更多地了解初始化失败的原因(如果重要的话)。
final class FailableFoo: NSObject {
let foo: String
enum FailableFooInitializationError: LocalizedError {
case somethingWentWrong
}
required init?(error: inout Error?) {
foo = "Foo"
let somethingWentWrong = true
if somethingWentWrong {
error = FailableFooInitializationError.somethingWentWrong
return nil
} else {
super.init()
}
}
}
final class Bar: NSObject {
let foo: FailibleFoo?
override init() {
var fooInitializationError: Error? = nil
foo = FailableFoo(error: &fooInitializationError)
if let fooInitializationError = fooInitializationError {
// handle init error
}
super.init()
}
}