Ios 如何在自定义初始值设定项的swift中返回nil?

Ios 如何在自定义初始值设定项的swift中返回nil?,ios,swift,convenience-methods,Ios,Swift,Convenience Methods,我正在尝试用swift编写自定义初始值设定项。 我有这样的想法: convenience init(datasource:SomeProtocol) { assert(datasource != nil, "Invalid datasource") if(datasource == nil) { return nil } self.init() } “return nil”行给出了以下错误:“找不到接受所提供参数的“\uu conversion”

我正在尝试用swift编写自定义初始值设定项。 我有这样的想法:

convenience init(datasource:SomeProtocol) {
    assert(datasource != nil, "Invalid datasource")
    if(datasource == nil) {
        return nil
    }
    self.init()
}
“return nil”行给出了以下错误:“找不到接受所提供参数的“\uu conversion”的重载”

所以,我所要做的就是让这个方便的初始值设定项在调用者没有提供有效的数据源时返回nil

我做错了什么


谢谢

这是因为
初始值设定项
实际上没有返回任何值。如果方法不需要返回类型,则不能返回
nil


要实现您想要做的事情(即强制您的类拥有一个数据源),只需将您的数据源设置为可选。非可选的变量必须有一个值(因此不能为零)并且必须初始化。

我认为这会起作用,尽管你的文章不清楚你在哪里使用数据源:

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

当然,现在可以从
init?(…)
返回
nil


如果该类的超类是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的超类时,这才有效。因此,这不是一个通用的解决方案。

更新:从Xcode 6.1 beta 1开始,可以声明Swift初始化程序返回可选的:

convenience init?(datasource:SomeProtocol) {
    if datasource == nil {
        return nil
    }
    self.init()
}
convenience init!(datasource:SomeProtocol) {
    if datasource == nil {
        return nil
    }
    self.init()
}
或隐式展开的可选项:

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

断言后,程序将不会继续执行。没有理由担心数据源为零的情况,现在有了解决这个问题的方法。你应该考虑改变你所接受的答案。你的代码工作,但效率不高。您将数据源设置为具有可选的(使用?),然后验证是否存在数据源。如果参数不是可选的(删除?),那么您将确保该值不是可选的,并且不必检查数据源是否有值。在这种情况下,使用if-let是没有用的,因为您不需要打开该值(您无论如何也不使用它)。@Emilie您是对的。无需将其设置为可选,然后将其展开。更改了代码。有没有一种方法可以使用初始值设定项而不是类方法?正如Emilie之前所说,init_xxx没有返回类型,所以不,不能返回nil。我认为数据源类型应该是可选的“SomeProtocol?”@SuryavelTR:问题就是这样;这与问题无关,所以我就不提了。它可能是可选的,但我想从理论上讲,
SomeProtocol
扩展了
NilLiteralConvertible
,或者一些不再准确的东西,因为Swift现在允许可选的初始值设定项。