2017-02-17 6 views
0

Swiftのドキュメントとさまざまなオンラインチュートリアルを読んだ後でも、参照型と値の型の間に私の頭を置くのは少し難しいです。Swiftのリファレンスと値の型の比較

私はSwiftのOOPアーキテクチャを理解するためのSwift TDDの本からのチュートリアルに従っています。このチュートリアルは、to do do appを作成することに基づいています。本の冒頭では、それぞれのアイテムに似せる構造体を作成しました。次に、アイテムを実行するために保持する配列を管理するItemMangerというクラスを作成し、アイテムを実行するためにチェックを保持する配列を作成しました。インスタンス化するたびに新しいインスタンスを作成する値型とクラスから作成されたitemManagerという理由から、構造体からアイテムを作成するというアイデアは理解できます。私が思いついた問題は、別のクラスまたはビューコントローラの中にあるItemManagerタイプ(クラス)のインスタンスを作成するときです。これは、前に作成した同じクラスを参照することになります。アイテム配列にアクセスするには?

この本の前に、私はクラスから変数を追跡することを前提としていましたが、それらを静的とマークする必要がありました。ここで

はitemManagerクラスです:あなたは作成ではありません投稿コードで

import UIKit 

enum Section: Int { 
    case toDo 
    case done 
} 

class ItemListDataProvider: NSObject, UITableViewDataSource, UITableViewDelegate { 

    var itemManager: ItemManager? 


    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 


     guard let itemManager = itemManager else{return 0} 

     guard let itemSection = Section(rawValue: section)else{ fatalError() } 

     let numberOfRows: Int 

     switch itemSection { 
     case .toDo: 
      numberOfRows = itemManager.toDoCount 
     case .done: 
      numberOfRows = itemManager.doneCount 
     } 

     return numberOfRows 
    } 

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 

     let cell = tableView.dequeueReusableCell(withIdentifier: "ItemCell", for: indexPath) as! ItemCell 

     guard let itemManager = itemManager else { fatalError() } 

     guard let section = Section(rawValue: indexPath.section) else { fatalError() } 

     let item: ToDoItem 

     switch section { 
     case .toDo: 
      item = itemManager.item(at: indexPath.row) 
     case .done: 
      item = itemManager.doneItem(at: indexPath.row) 
     } 

     cell.configCell(with: item) 

     return cell 
    } 

    func numberOfSections(in tableView: UITableView) -> Int { 
     return 2 
    } 
} 

答えて

2

:ここ

import Foundation 

class ItemManager { 

    var toDoCount: Int {return toDoItems.count } 

    var doneCount: Int {return doneItems.count } 

    private var toDoItems: [ToDoItem] = [] 

    private var doneItems: [ToDoItem] = [] 


    func add(item: ToDoItem) { 

     if !toDoItems.contains(item){ 
      toDoItems.append(item) 
     } 

    } 

    func checkItem(at index: Int) { 
     let item = toDoItems.remove(at: index) 
     doneItems.append(item) 
    } 

    func doneItem(at index: Int) -> ToDoItem{ 
     return doneItems[index] 
    } 

    func item(at index: Int) -> ToDoItem{ 
     return toDoItems[index] 
    } 

    func removeAll(){ 

     toDoItems.removeAll() 
     doneItems.removeAll() 
    } 

} 

たちはItemManager型のインスタンス変数を作成し、別のクラスでありますItemManagerのインスタンスここで

我々はItemManager型のインスタンス変数を作成して別のクラスである:

ItemListDataProviderItemManagerを持つことができますが、それは1を作成しません。あなたの商品マネージャーが作成された場所が表示されていなかったので、質問

は、この私たちが作成した同じクラスを参照します

// Creates an instance of ItemManager and assigns it to itemManager 
let itemManager = ItemManager() 

:クラスのインスタンスを作成すると、それは、このようなコンストラクタの呼び出しによって動作します以前はアイテム配列を操作するためにアクセスできますか?

は本当に答えられません。 ItemManagerのインスタンスはどこで作成しましたか?それで何をしましたか?ここ

は一例であり:

let itemManagerA = ItemManager() 

let itemListDataProviderA() = ItemListDataProvider() 
itemListDataProviderA.itemManager = itemManagerA 

let itemListDataProviderB() = ItemListDataProvider() 
itemListDataProviderB.itemManager = itemManagerA 

この例で両方ItemListProvider sが同じItemManagerを有し、したがって同じアイテムアレイへのアクセスを有します。

let itemManagerA = ItemManager() 
let itemListDataProviderA() = ItemListDataProvider() 
itemListDataProviderA.itemManager = itemManagerA 

let itemManagerB = ItemManager() // <-- This creates a SECOND instance of ItemManager 
let itemListDataProviderB() = ItemListDataProvider() 
itemListDataProviderB.itemManager = itemManagerB // <-- We use the SECOND instance instead of the first one for itemListDataProviderB 

両方ItemListProvider sがItemListProvider異なるインスタンスがが同じ項目へのアクセスを持っていない持っている:あなたはこのような何かをやっている場合は逆に