简体   繁体   中英

Inter Object Parent/Child Communication in Swift

I have a view controller that contains instances (objects) of a few related classes that need to intercommunicate.

I can easily set these up by creating instances of the objects within the VC:

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

But how do I get a method in the House object to 'speak'/send data to the Road object? In some languages I could invoke the parent object and target the other class and its methods that way:

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

Obviously the _parent keyword is not swift code so won't work.

The only way I can think of doing this is to create an instance of road inside the House object as a child object, thus exposing it directly in scope to the method code. Having a lot of external code in the VC to do all the heavy lifting is another idea that seems like bad practice and inelegant.

Any ideas?

Many thanks. Kw

One way would be to use the Delegation pattern. Each class should declare a protocol with all the messages it can send, and the class that needs to listen to those messages should implement the protocol, register as the (or one of the) delegate(s) and respond accordingly.

Here's a good example how to implement Delegation Pattern .

And a sample implementation for your objects:

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"

Best way to handle this is by using mediator pattern, if you need to establish communication between House, Road, Town you can set it in a way that they communicate to 'mediator' (parent object). In this case parent object can mediate and coordinate between the objects

Or, you can use NSNotificationCenter, post a notification from one object and listen to the notification in another object, but this is hard to track as soon as your app gets more complex.

Let's say the Word class is parent class of the House, Road, Town. Here you can establish communication between Word, House and Town, and inter-communication between House and Town. Be advised this is more pseudo code I'm writting it in browser but you'll get idea

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) {
        // .....
    }
}

The same thing above can be accomplished via delegation but I like blocks more. Basically you have 3 options: Notifications (the worst), delegation or callbacks.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM