web-dev-qa-db-ja.com

カスタム初期化子でSwiftでnilを返す方法は?

Swiftでカスタム初期化子を記述しようとしています。私はこのようなものを持っています:

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

「return nil」行で次のエラーが発生します。「指定された引数を受け入れる '__conversion'のオーバーロードが見つかりませんでした」

したがって、私が達成しようとしているのは、呼び出し側が有効なデータソースを提供しない場合に、この便利なイニシャライザがnilを返すようにすることです。

ここで何が悪いのですか?

ありがとう

18
zumzum

これは、initializersには実際には値が返されないためです。メソッドが戻り値の型を期待していない場合、nilを返すことはできません。

実行しようとしていることを実現するには(つまり、クラスにデータソースを強制する)、データソースnotをオプションにします。オプションではない変数mustには値があり(nilにはできません)、初期化する必要があります。

2
Emilie

Update:Xcode 6.1 beta 1以降 (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()
}
46
user102008

これはうまくいくと思いますが、dataSourceを操作している投稿からは明らかではありません。

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

更新Swift

もちろん、init?(...)からnilを返すことができます。

_init?(datasource: A){
    if datasource.isValid() {
        // initialise your properties from datasource
    } else {
        return nil
    }
}
_
10
Grimxn

このクラスのスーパークラスが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を返すスーパークラスを持つ幸運な場合にのみ機能します。したがって、これは一般的な解決策ではありません。

1
user102008