2016-05-05 10 views
1

私は相互通信が必要ないくつかの関連するクラスのインスタンス(オブジェクト)を含むView Controllerを持っています。スウィフトでのオブジェクト間の親子通信

私は簡単にVC内のオブジェクトのインスタンスを作成することによって、これらを設定することができます。

var house = House() 
var road = Road() 
var town = Town() 

しかし、どのように、私は「話す」に/ロードオブジェクトにデータを送信するハウスオブジェクトのメソッドを得るのですか?私は親オブジェクトを呼び出すと、そのように他のクラスとそのメソッドをターゲット可能性がいくつかの言語では:

func sendHouseData (num: Int) { 
_parent.road.getHouseData (num) 
} 

明らか_parentキーワードはそれほど機能しません迅速なコードではありません。

私が考えることができる唯一の方法は、ハウスオブジェクト内の道路のインスタンスを子オブジェクトとして作成し、それをメソッドコードのスコープ内に直接公開することです。 VCに多くの外部コードを持たせることは、すべての重労働を行うことは悪い習慣であり、控えめな考えです。

アイデア?

多くのありがとうございます。 Kw

+0

はタウンクラスの親クラスですか? – marosoaie

+0

通常、関連オブジェクトに必要に応じて参照が保持されます。だから、家はその道への参照を保持し、道路はその町への参照を持っています。次に、あなたは 'self.myRoad.someFunction()'のようなものを言うでしょう。 – Paulw11

+0

@marosoaie彼らはクラス階層ではなく、単に関連するクラスだと思います。 – Paulw11

答えて

3

委任パターンを使用する方法もあります。各クラスは、送信可能なすべてのメッセージを含むプロトコルを宣言する必要があります。これらのメッセージを受信するクラスは、プロトコルを実装し、代理人として登録し、それに応じて応答する必要があります。

ここでは、Delegation Patternの実装方法の良い例を示します。

そして、あなたのオブジェクトのためのサンプル実装:これを処理する

protocol HouseDelegate { 
    func readData(data:Int) 
} 

class House { 
    var delegate:HouseDelegate 
    var data:Int = 0 

    init(delegate:HouseDelegate) { 
     self.delegate = delegate 
    } 

    func sendData() { 
     self.delegate.readData(data) 
    } 
} 

class Road: HouseDelegate { 

    var data:Int = 0 
    func readData(data: Int) { 
     print("Read data \(data)") 
     self.data = data 
    } 
} 

var road = Road() 

var house = House (delegate: road) 

house.sendData() //prints "Read data 0" 
+0

保持ループを防ぐには、 – Paulw11

+0

@ Paulw11これは親子関係の場合に当てはまります。この例では、彼らは同じレベルにいると信じています。 – marosoaie

+1

いいえ、彼らはほとんど常に弱いはずです。あなたはどのように誰かがクラスを使用することを選択するかわからないので、弱いを使用することが最も安全です – Paulw11

1

最善の方法は、あなたが家、道路、町間の通信を確立する必要がある場合は、その方法でそれを設定することができ、Mediatorパターンを使用することです彼らは「仲介者」(親オブジェクト)と通信します。この場合、親オブジェクトはオブジェクト間で仲介と調整を行うことができます

または、NSNotificationCenterを使用して1つのオブジェクトから通知を送信し、別のオブジェクトの通知を聞くことができますが、もっと複雑です。

WordクラスがHouse、Road、Townの親クラスであるとします。 ここでは、Word、HouseとTownの間の通信、およびHouseとTownの間の通信を確立できます。これは私がブラウザでそれを足すだよりの擬似コードであることをお勧めすること が、あなたのアイデア

class Word { 

    let house = House() 
    let town = Town() 

    init() { 
     // Here World will be notified when the house hasReceivedVisitor and the town hasBuiltRoad. 
     self.house.hasReceivedVisitor = { visitorName in 
      print("\(visitorName) has visited the house!") 
      // Communication between house and town ... 
      self.town.doSometingWithVisitor(visitorName) 
     } 

     self.town.hasBuiltRoad = { roadNumber in 
      print("A road \(roadNumber) has been built!") 
      // Communication between town and house ... 
      self.house.doSometingWithRoad(roadNumber) 
     } 
    } 
} 

class House { 

    var hasReceivedVisitor: ((vistorName: String) ->())? 

    func createVisitor() { 
     let vistor = Visitor("Mike") 
     self.hasReceivedVisitor?(vistor.vistorName) 
    } 

    func doSometingWithRoad(roadNumber: Int) { 
     // ..... 
    } 
} 

class Town { 

    var hasBuiltRoad: ((roadNumber: Int) ->())? 

    func createRoad() { 
     let road = Road(66) 
     self.hasBuiltRoad?(road.roadNumber) 
    } 

    func doSometingWithVisitor(visitorName: String) { 
     // ..... 
    } 
} 

を得ることができます上記と同じことは、委任を介して達成することができるが、私はより多くのブロックが好き。 基本的には、通知(最悪)、委任またはコールバックの3つのオプションがあります。

+0

有用で詳細なアドバイスありがとう。私は親オブジェクトをその子オブジェクトへの中間として使用して、これに似たことをしました。その少し不器用ですが、大丈夫です。 – Kwangle

関連する問題