NSObject子类的无参数Failable初始值设定项

Gle*_*n T 11 ios swift

我想为NSObject子类提供一个可用的初始化程序,用于初始化而不带参数.我的总体目标是返回nil这个类在小于8.0的OS版本上初始化.

我的尝试如下:

class MyObject: NSObject {
    override init?() {
        super.init()
        if floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_7_1 {
            return nil
        }

    }
}
Run Code Online (Sandbox Code Playgroud)

但是,此代码会导致以下编译器错误.

Failable initializer 'init()' cannot override a non-failable initializer
Run Code Online (Sandbox Code Playgroud)

是否可以覆盖init()以在子类中提供可用的实现?或者有更好的方法来实现这一目标吗?

Ant*_*nio 6

鉴于:

您可以使用不可失败的初始化程序覆盖可失败的初始化程序,但反之则不然。

可失败的初始化程序也可以委托给不可失败的初始化程序。如果您需要向现有的初始化过程添加潜在的失败状态(否则不会失败),请使用此方法。

(摘自失败的初始化器

并考虑到NSObject没有无参数可失败初始化程序,那么不,您不能使用可失败初始化程序覆盖不可失败初始化程序。

我看到的唯一选择是创建一个带有虚拟参数的初始值设定项,例如:

class MyObject: NSObject {
    init?(_ ignore: Bool) {
        super.init()
        if floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_7_1 {
            return nil
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后将其用作:

var myObj = MyObject(true)
Run Code Online (Sandbox Code Playgroud)

或者

var myObj = MyObject(false)
Run Code Online (Sandbox Code Playgroud)

更有趣的是,为虚拟参数分配默认值似乎可以很好地完成这项工作:

class MyObject: NSObject {
    init?(_ ignore: Bool = false) {
        super.init()
        if floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_7_1 {
            return nil
        }
    }
}

var myObj = MyObject()
Run Code Online (Sandbox Code Playgroud)

  • 带有默认值的虚拟参数解决方案虽然邪恶,但却很出色。 (2认同)

Pau*_*w11 5

当你继承 NSObject 时,你不能有一个可失败的无参数初始化器,因为 NSObject 的无参数初始化器是不可失败的。

您可以创建一个类工厂方法,根据 iOS 版本返回实例或 nil