我正在尝试在swift中编写自定义初始化程序。 我有这样的事情:
convenience init(datasource:SomeProtocol) {
assert(datasource != nil, "Invalid datasource")
if(datasource == nil) {
return nil
}
self.init()
}
"返回nil" line给了我这个错误:"找不到' __转换的重载'接受提供的参数"
所以,我想要完成的就是让这个方便的初始化器返回nil,如果调用者没有提供有效的数据源。
我在这里做错了什么?
由于
答案 0 :(得分:42)
更新:从Xcode 6.1 beta 1 (available in the Mac Dev Center)开始,可以声明Swift初始化程序返回一个可选项:
convenience init?(datasource:SomeProtocol) {
if datasource == nil {
return nil
}
self.init()
}
或隐式解包的选项:
convenience init!(datasource:SomeProtocol) {
if datasource == nil {
return nil
}
self.init()
}
答案 1 :(得分:9)
我认为这样可行,但您在帖子中使用dataSource的地方并不清楚:
class func instOrNil(datasource:A) -> Self? {
// do something with datasource
if datasource.isValid() {
return self()
} else {
return nil
}
}
更新Swift 3
您当然可以从nil
init?(...)
init?(datasource: A){
if datasource.isValid() {
// initialise your properties from datasource
} else {
return nil
}
}
答案 2 :(得分:3)
这是因为initializers
实际上没有返回任何价值。如果方法不期望返回类型,则无法返回nil
。
要实现您的目标(即强制您的课程拥有数据源),只需将您的数据源不作为可选项。非可选的变量必须具有值(因此不能为零)并且必须初始化。
答案 3 :(得分:1)
如果这个类的超类是Objective-C类,并且你知道有一些输入会导致它的初始化器返回nil
,你可以简单地将该输入传递给超类&#39 ; s初始化程序,这将导致初始化程序返回nil
:
import Foundation
class Foo : NSURL {
convenience init(x: Int) {
if x == 42 {
self.init(string: "http://www.google.com/")
} else {
self.init(string: "not a url") // returns nil
}
}
}
let a: Foo? = Foo(x: 42)
println(a) // prints "Optional(http://www.google.com/)"
let b: Foo? = Foo(x: 17)
println(b) // prints "nil"
当然,只有当你足够幸运拥有一个初始化程序将返回nil的超类时,这才有效。所以这不是一般解决方案。