Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create an array of classes and instance objects with it in Swift?

Tags:

generics

swift

I tried to ask this question previously but didn't clearly express my question, so I'll try again here. I also noticed a very similar sounding question, but it is asking for something entirely different.

I have the following code:

class Base {
    func launch(code1: Int, code2: Int) { ... }
}

class A: Base {}
class B: Base {}
class C: Base {}

let classes = [A.self, B.self, A.self, B.self, C.self]
for cls in classes {
    let obj = ???
}

I would like to instantiate an object of type cls inside the loop and do something with it. I might have duplicates inside the array, as shown. What do I put in place of the ??? to be able to instantiate the proper objects?

like image 377
Ana Avatar asked Dec 01 '15 17:12

Ana


People also ask

How do I initialize an array in Swift?

To initialize a set with predefined list of unique elements, Swift allows to use the array literal for sets. The initial elements are comma separated and enclosed in square brackets: [element1, element2, ..., elementN] .

How do you create an array of strings in Swift?

Swift makes it easy to create arrays in your code using an array literal: simply surround a comma-separated list of values with square brackets. Without any other information, Swift creates an array that includes the specified values, automatically inferring the array's Element type.

How do you declare an array variable in Swift?

Array in swift is written as **Array < Element > **, where Element is the type of values the array is allowed to store. The type of the emptyArray variable is inferred to be [String] from the type of the initializer. The groceryList variable is declared as “an array of string values”, written as [String].


1 Answers

All you need is a required init, some way to create an instance that will be shared between all Types you want this to work for. A protocol that holds an init method will do fine.

Obviously this works simplest when the init does not require parameters.

Downside is that you do need to downcast the resulting instances.

protocol ZeroParamaterInit {
    init()
}

class Base : ZeroParamaterInit {
    func launch(code1: Int, code2: Int) {  }
    required init() {

    }
}

class A: Base {}
class B: Base {}
class C: Base {}

let classes : [ZeroParamaterInit.Type] = [A.self,B.self]
var instances : [Any] = []

for cls in classes {

    let instance = cls.init()
    instances.append(instance)

}

for instance in instances {

    if let test = instance as? A {
        print("A")
    }
    if let test = instance as? B {
        print("B")
    }
    if let test = instance as? C {
        print("C")
    }
}
like image 85
R Menke Avatar answered Oct 12 '22 00:10

R Menke