21

我正在尝试快速编写自定义初始化程序。我有这样的事情:

convenience init(datasource:SomeProtocol) {
    assert(datasource != nil, "Invalid datasource")
    if(datasource == nil) {
        return nil
    }
    self.init()
}

“return nil”行给了我这个错误:“找不到接受提供的参数的 '__conversion' 的重载”

所以,我想要完成的只是让这个便利初始化程序在调用者没有提供有效数据源的情况下返回 nil。

我在这里做错了什么?

谢谢

4

4 回答 4

49

更新:从 Xcode 6.1 beta 1 (可在 Mac 开发中心获得)开始,Swift 初始化器可以声明为返回一个可选的:

convenience init?(datasource:SomeProtocol) {
    if datasource == nil {
        return nil
    }
    self.init()
}

或隐式展开的可选:

convenience init!(datasource:SomeProtocol) {
    if datasource == nil {
        return nil
    }
    self.init()
}
于 2014-09-15T02:41:37.873 回答
13

我认为这会起作用,尽管从您的帖子中不清楚您在哪里使用数据源:

class func instOrNil(datasource:A) -> Self? {
    // do something with datasource
    if datasource.isValid() {
        return self()
    } else {
        return nil
    }
}

更新斯威夫特 3

当然,您现在可以nil从 a返回init?(...)

init?(datasource: A){
    if datasource.isValid() {
        // initialise your properties from datasource
    } else {
        return nil
    }
}
于 2014-06-12T17:53:16.170 回答
2

这是因为initializers实际上没有返回任何值。如果nil方法不期望返回类型,则无法返回。

为了实现你想要做的事情(即强制你的类有一个数据源),只需让你的数据源不是可选的。非可选变量必须有值(因此不能为 nil)并且必须初始化。

于 2014-06-12T17:01:20.193 回答
1

如果这个类的超类是一个 Objective-C 类,并且你知道有一些输入会导致它的初始化程序返回nil,你可以简单地将该输入传递给超类的初始化程序,这将导致你的初始化程序返回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 的超类时才有效。所以这不是一个通用的解决方案。

于 2014-08-11T06:16:49.237 回答