7

Effectively, I want to have a protocol that will return a Metatype (e.g.: Type.Type), which I can pass to a Class, and then when I need to, cast an object to that MetaType. The reason I'm to cast it is that it will be used in a tableView dequeue function, and I want to cast to the Type I've assigned.

Consider this condensed version (full version below).

let anyObject: AnyObject = anything()

let aType = type.type() // aType here is A.Type

if let newType = anyObject as? aType {

    print(newType)
}

// error: 'aType' is not a type

I'm confused why this is not a type, since we can go aType.init() to initialise it?

The full sample code is below (and is OK to run in a Playground).

import UIKit

protocol P {

    func type() -> A.Type
}

class A {

}

class B: A {

}

class C: A {

}

struct BData: P {

    func type() -> A.Type {

        return B.self
    }
}

struct Foo {

    let type: P

    init(p: P) {

        self.type = p
    }

    func create() {

        let anyObject: AnyObject = anything()

        let typeType = type.type()

        if let newType = anyObject as? typeType {

            print(newType)
        }
    }

    func anything() -> AnyObject {

        return B()
    }
}

let data = BData()

let foo = Foo(p: data)

Playground execution failed: MyPlayground.playground:43:44: error: 'typeType' is not a type if let newType = anyObject as? typeType {

chillok
  • 235
  • 1
  • 3
  • 11

1 Answers1

9

Ahmm. Very nice question. I had same 3-hours-pain few days ago. Finally, i found this answer, that main idea is:

Swift's static typing means the type of a variable must be known at compile time.

So, the way you coding unfortunately (or fortunately :) ) not allowed.

Community
  • 1
  • 1
pacification
  • 5,838
  • 4
  • 29
  • 51
  • Aw :'( Why fortunately, would you say? – chillok Apr 22 '16 at 18:45
  • @cilk, well, i have another answer for you, man :) http://stackoverflow.com/a/1517670/2463616 – pacification Apr 22 '16 at 18:50
  • Ah yeah, fair enough. Great for safety until I want to be unsafe.. Did you approach an alternate solution? – chillok Apr 22 '16 at 19:10
  • ah well, I'll find some way :) – chillok Apr 22 '16 at 19:17
  • In my use case, I actually didn't need to cast to the Type itself. The Type was always a subclass, and the information I was passing would always go to the Type's super, so I cast to the super instead. What's weird is that I did need to access a class method on the type, which it did allow me to do. `cell = collectionView.dequeueReusableCellWithReuseIdentifier(type.reuseIdentifierId, forIndexPath: indexPath) as? SuperType` Were `type` is the metatype in question! – chillok Apr 25 '16 at 10:26