2017-02-21 4 views
1

私はSwiftの本を使っています。関数のスコープの考え方を理解していますので、次に理解したいのは、クラスでオプションの型を使ってグローバル変数を設定する理由です。正直なところ、これらの変数を設定するのではなく、コードベースのどこかに特定の型の変数、つまりvar sut: ItemManager!があることをクラスに知らせるように見えます。swiftでオプションのグローバル変数を理解する

私が知っているから、変数sutは、明らかに有効な値を持ち、nilではないItemManger型のアンラップされたオプションです。私たちが感嘆符または疑問符でそれを設定した理由は、このクラス内にイニシャライザがないためです。このクラスに初期化子がないため、このグローバル変数を疑問符を使用してオプションに設定する天気を決定するとき、または感嘆符で暗黙的にアンラップしたときに、どのような要素が影響しますか?

import XCTest 
    @testable import ToDo 

    class ItemManagerTests: XCTestCase { 

     var sut: ItemManager! 

     override func setUp() { 
      super.setUp() 
      // Put setup code here. This method is called before the invocation of each test method in the class. 

      sut = ItemManager.init() 
     } 

     override func tearDown() { 
      // Put teardown code here. This method is called after the invocation of each test method in the class. 
      super.tearDown() 
     } 


     func test_ToDoCount_InitiallySetAtZero(){ 

      let sut = ItemManager.init() 

      XCTAssertEqual(sut.toDoCount, 0) 
     } 

     func test_DoneCount_InitiallySetAtZero(){ 

      let sut = ItemManager.init() 

      XCTAssertEqual(sut.doneCount, 0) 
     } 
    } 

答えて

0

クラスのすべてのインスタンスが初期化されるとき、それは持っているので、このクラス内の初期化子

がないため、我々は感嘆符や疑問符でそれを設定した理由は ですそのプロパティ/インスタンスvarにメモリを割り当てます。したがって、var sut: ItemManager!の場合、sutの値は、initの場合、nilとなります。 !がなければ、?コンパイラはinitを割り当てることができないので、イニシャライザで手動でinitを起動する必要があります。それはコンパイラがあなたに語ったものです。

!または?を使用する場合。

  • !は、プロパティ/ varが最初の割り当て後に常に値を持つ場合に使用されます。そして、それが割り当てられている最初の時間の後に、それはプロ/ varが値を持つことができるかどうか
+1

あなたのリストの最初の項目にはクレームも正しくありません。 IUOが価値を持たないことは間違いありません。あなたが誰かなしでアクセスしないようにしてください。 – Andreas

3

sutはグローバル変数ではありません。

sutItemManagerTestsのインスタンス変数です。 ItemManagerTestsの新しいインスタンス、すなわちオブジェクトがインスタンス化されるたびに、sutのためにメモリが割り当てられる。

ItemManager!です。暗黙のうちにアンラップされたオプションです。 ItemManager?(a.k.a.省略可能)と似ていますが、力のアンラップ演算子(!)が使用されたかのように、直接使用されている場所では暗黙的に強制的にアンラップされるという違いがあります。

この値はnilに初期化されますが、setUpがXcodeのテストフレームワークによって呼び出されると、新しいItemManagerオブジェクトに設定されます。

3

はまず、sutがグローバルでないときに使用され、後に

  • ? nilをすることはできません。 Swiftのグローバル変数は、囲みスコープの外で宣言されます(したがって、classステートメントの前)。 sutはインスタンスプロパティです。 ItemManagerTestsクラスの各インスタンスはsutプロパティを持ちます。

    Swiftでは、オプションではないプロパティはすべて、初期設定が完了するまでに初期化する必要があります。場合によっては、初期値の内部にコードを設定し、その他の場合はデフォルト値を設定することで実現できます。

    場合によっては、デフォルト値を割り当てることができない、または割り当てたくないし、イニシャライザをオーバーライドできない(またはしたくない)ことがあります。

    オプションのノーマルを使用した場合、コンパイラは、プロパティは、デフォルトまたは初期化子で初期化されていなかったが、あなたはプロパティを参照するたびに、あなたが(例えばsut?.donecount)それをアンラップしなければならないことに満足することでしょう。

    テストケースがsetupsutに値を代入しているので、あなたはそれが価値を持つことになりますし、あなたが力アンラップ(例えばsut!.donecount)を使用することができ、または、さらに一歩それを取るとオプションの暗黙的に開封されたを使用することを知っています。これにより、アンラッピングなしでプロパティを参照することができますが、依然としてオプションであり、nilの場合でもクラッシュが発生します。

    テストケースにローカル変数を割り当てるため、現在のコードではプロパティを使用していないことに注意してください。あなたは以下を使用することができます:

    class ItemManagerTests: XCTestCase { 
    
        var sut: ItemManager! 
    
        override func setUp() { 
         super.setUp() 
         // Put setup code here. This method is called before the invocation of each test method in the class. 
    
         sut = ItemManager.init() 
        } 
    
        override func tearDown() { 
         // Put teardown code here. This method is called after the invocation of each test method in the class. 
         super.tearDown() 
        } 
    
        func test_ToDoCount_InitiallySetAtZero() { 
    
         XCTAssertEqual(sut.toDoCount, 0) 
        } 
    
        func test_DoneCount_InitiallySetAtZero() { 
    
         XCTAssertEqual(sut.doneCount, 0) 
        } 
    } 
    
  • 関連する問題