1

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 :)

4
  • AnyClass exists, but Swift does not really want you to pass class types around. What is the real goal here? There is probably a much better way. Commented May 16, 2020 at 12:21
  • @matt I updated my question to tell what I'm trying to achieve. Commented May 16, 2020 at 12:49
  • Aren't you better off with [UITableViewCell.Type], then? Commented May 16, 2020 at 12:54
  • That's a much better question! Commented May 16, 2020 at 13:00

4 Answers 4

1

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)
Sign up to request clarification or add additional context in comments.

Comments

1

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")
        }
    }

Comments

0

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).

Comments

0

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])

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.