instantiate from protocol.Type reference dynamically at runtime

Refresh

November 2018

Views

1.6k time

3

I've asked this question earlier at so you get to know a bit of history, It was an awesome attempt by Airspeed Velocity there but I feel I didn't quite get there yet, so I'm narrowing down my question to very minute details in order to really crack it down.

swift program to interface

You may complain or down vote that question is incomplete but that's how it goes, It's based on design patterns, so if you're not familiar with design patterns or philosophy "Program to interface not to an implementation" then don't complaint or down vote.

Looking out for SWIFT guru's who can crack it down.

All the best.

public protocol IAnimal {
    init()
    func speak()
}

class Test {
     func instantiateAndCallSpeak(animal:IAnimal.Type) {
         //use the animal variable to instantiate and call speak - 
         //no implementation classes are known to this method
         //simply instantiate from the IAnimal reference at run time.
         //assume the object coming in via does implement the protocol (compiler checks that)

     }
}

Edit Awesome Martin... you cracked it. sorry I missed this part,

suppose if you've an array of all those implementation classes, how'd you iterate instantiate and call speak (remember implementation class Cat in this case is not known to the test)

var animals:[IAnimal.Type] = [Cat.self, Dog.self, Cow.self] 

//and so many more implementation classes not known to test method

//my attempt in playground causing some issues with it, compiler thrown an error Segmentation fault11

for animal in animals {
    let instance = animal()
    instance.speak()
}

1 answers

4

Вы можете добиться того, что с помощью обобщенной функции:

class Test {
    func instantiateAndCallSpeak<T: IAnimal>(animal:T.Type) {
        let theAnimal = animal()
        theAnimal.speak()
    }
}

Пример:

class Cat : IAnimal {
    required init() {
    }
    func speak() {
        println("Miau"); // This is a german cat
    }
}

// ...

let t = Test()
t.instantiateAndCallSpeak(Cat.self) // --> Miau