2017-04-12 3 views
3

staticの変数が暗黙的にlazyであることがわかりました。これは本当に素晴らしいです。インスタンスを作成しません下記やって、それが最初に呼び出されるまで:遅延静的変数を設定すると、最初に初期化してから割り当てますか?

SomeType.test = AnotherTest() //Initializes Test then AnotherTest type 
static変数に新しいインスタンスを割り当て、しかし

static var test = Test() 

を元に初期化し、その後、私のために悩まれている新しいインスタンスを割り当て

私は何をしようとしているのかをさらに詳しく知るために、this articleを使って純粋なSwift依存性注入をセットアップしようとしています。私の単体テストで型を交換するとうまくいきません。なぜなら元の型はモック型を割り当てるときに常に初期化されるからです。

はここで、より充実し、遊び場のサンプルです:

protocol MyProtocol { } 

class MyClass: MyProtocol { 
    init() { print("MyClass.init") } 
} 

//// 

struct MyMap { 
    static var prop1: MyProtocol = MyClass() 
} 

protocol MyInject { 

} 

extension MyInject { 
    var prop1: MyProtocol { return MyMap.prop1 } 
} 

//// 

class MyMock: MyProtocol { 
    init() { print("MyMock.init") } 
} 

// Swapping types underneath first initializes 
// original type, then mock type :(
MyMap.prop1 = MyMock() 

prints: MyClass.init 
prints: MyMock.init 

にはどうすればMyMap.prop1 = MyMock()は、まず、第1のオリジナルMyClassを初期化できませんすることができますか?

答えて

2

遅延読み込みが必要です。これを試してみてください:

struct MyMap { 
    private static var _prop1: MyProtocol? 
    static var prop1: MyProtocol { 
     get { return _prop1 ?? MyClass() } 
     set(value) { _prop1 = value } 
    } 
} 

それともこれを:

struct MyMap { 
    private static var _prop1: MyProtocol? 
    static var prop1: MyProtocol { 
     get { 
      if _prop1 == nil { 
       _prop1 = MyClass() 
      } 
      return _prop1! 
     } 
     set(value) { _prop1 = value } 
    } 
} 
+0

おっと、なぜこの作品?? ...これはスウィフトのバグですか、これは意図的でしたか!? – TruMan1

+1

これはswiftによって意図されています。 varは存在する限り値を必要とします。この値は、ゼロまたは具体的な値です。あなたのvarは定義によって無限になることはできません。したがって、値を指定する必要があります(またはコンパイル時にエラーが発生します)。 getやsetを呼び出すかどうかは関係ありません。 Swiftはあなたのvarがそれを扱う前に価値があることを保証しなければなりません。アップルが "迅速な救済"と呼んでいること – ObjectAlchemist

+0

@codealchimistしかし、 'static'に格納されたプロパティは遅延ロードされています。ロードされる前に最初に割り当てられていればプロパティ初期化子を呼び出す*べきではありません。しかし、それは現在のところスウィフトがどのようにふるまうかです。 – Hamish

関連する問題