matchifang
matchifang

Reputation: 5450

How to accept array of class type as parameter

I'd like to pass an array of class types as parameter to a function, how can I do that?

Code:

let classList = [Class1.self, Class2.self, Class3.self]
myFunction(classList)    // how would I write the parameter for this?

Goal: I created a UITableView extension to shorten registering nibs and you can call it using tableView.register(CellClass.self). The function signature is func register<T>(_ cellType: T.Type)

Given that, I'm trying to create a register cells function where I want to do something like this:

func registerCells(classTypes: [XXXX]) {
     classTypes { (classType) in
        tableView.register(YYYY)
     }
}

and call it using tableView.resigterCells([Class1.self, Class2.self, Class3.self])

I'm not sure if this is possible in Swift. Please advise :)

Upvotes: 1

Views: 513

Answers (4)

matt
matt

Reputation: 534977

You can certainly do this:

func registerOneCellType(_ type: UITableViewCell.Type) {}
func registerCellTypes(_ types:[UITableViewCell.Type]) {
    for type in types {
        registerOneCellType(type)
    }
}
class CellType1: UITableViewCell {}
class CellType2: UITableViewCell {}
registerCellTypes([CellType1.self, CellType2.self])

But you know something? I wouldn't! I would pass actual cell objects and take their type and go from there. Swift is a lot more pleasant when you pass instances rather than types.

func registerOneType(ofCell: UITableViewCell) {}
func registerTypes(ofCells: [UITableViewCell]) {
    for cell in ofCells {
        registerOneType(ofCell: cell)
    }
}
class CellType1: UITableViewCell {}
class CellType2: UITableViewCell {}
registerTypes(ofCells: [CellType1(), CellType2()])

Inside registerOneType I would call type(of:) to get the type, and off you go. Note that you don't need a generic here (as far as I can tell).

Upvotes: 0

Gereon
Gereon

Reputation: 17844

If you know all your classes will be subclasses of UITableViewCell, I would suggest saying so in your code:

class X: UITableViewCell {}
class Y: UITableViewCell {}
class Z: UITableViewCell {}

func registerCells(classTypes: [UITableViewCell.Type]) {
    classTypes.forEach {
        tableView.register($0, forCellReuseIdentifier: "foo")
    }
}

registerCells(classTypes: [X.self, Y.self, Z.self])

Upvotes: 0

Jawad Ali
Jawad Ali

Reputation: 14397

AnyClass is type alias for AnyObject.Type. That means that it's a metatype which can hold any 'classtype'

class A {}
class B {}
class C {}

let classList : [AnyClass] = [A.self, B.self, C.self]

 perfornAction(classList)

Then function can be written as

func perfornAction(_ list:[AnyClass]) { 
        if let abc = list[0] as? A.Type{
            print("A")
        }
    }

Upvotes: 1

Luca Angeletti
Luca Angeletti

Reputation: 59496

If you want to be able to put any class type into the array, then you need to use [AnyObject.Type] as a type.

Here's the example

class A { }
class B { }
class C { }

let elms: [AnyObject.Type] = [A.self, B.self, C.self]

func foo(elms: [AnyObject.Type]) {
    print(elms)
}

foo(elms: elms)

Upvotes: 1

Related Questions