I'm trying to understand where this code went wrong given the code below. In the code below, I'm trying to locate a UIViewController of a specific class in the UITabBarController's viewControllers property which is declared as:
var viewControllers: [AnyObject]?
So I'm defining two UIViewController subclasses and stuffing them to the viewControllers array and running two different methods to extract them "viewControllerInfo:" ""viewControllerInfo2". Which both yield the same result.
My understanding is the:
if let x as? T
will evaluate true and assign x as a "T" type if it is the same class.
Just as if x is T
would.
Any idea why evaluation is behaving like this ?
class VC1: UIViewController {}
class VC2: UIViewController {}
let tabBar = UITabBarController()
tabBar.viewControllers = [VC1(), VC2()]
extension UITabBarController {
public func viewControllerInfo<T: UIViewController>(ofType: T.Type) -> (viewController: T,index: Int)? {
if let tabViewControllers = self.viewControllers{
for (idx, maybeVCTypeT) in enumerate(tabViewControllers) {
if let viewController = maybeVCTypeT as? T {
return (viewController, idx)
}
}
}
return nil
}
public func viewControllerInfo2<T: UIViewController>(ofType: T.Type) -> (viewController: T,index: Int)? {
if let tabViewControllers = self.viewControllers{
for (idx, maybeVCTypeT) in enumerate(tabViewControllers) {
if maybeVCTypeT is T {
return (maybeVCTypeT as! T, idx)
}
}
}
return nil
}
}
All the tests below will end up giving exactly the same result: "<__lldb_expr_89.VC1: 0x7f85016079f0>"
if let (vc, idx) = tabBar.viewControllerInfo(VC1.self) {
println(vc)
}
if let (vc, idx) = tabBar.viewControllerInfo(VC2.self) {
println(vc)
}
if let (vc, idx) = tabBar.viewControllerInfo2(VC1.self) {
println(vc)
}
if let (vc, idx) = tabBar.viewControllerInfo2(VC2.self) {
println(vc)
}
I'm suspicious of the enumerate(x) since without it I'm getting expected results:
if testVC1 is VC2 {
println("\(testVC1) is \(VC2.self)")
}
the above code yields a warning:
Cast from 'VC1' to unrelated type 'VC2' always fails Which is what i'm trying to achieve with enumerate...
***************** EDIT *****************
Actually my suspicion of enumerate is dissolved after running the following code which ran perfectly.
let myArray: [AnyObject] = [VC2(), VC1()]
for (idx, x) in enumerate(myArray) {
println(x)
if let xAsVC1 = x as? VC1 {
println("\(x) is supposed to be \(VC1.self)")
//"<__lldb_expr_155.VC1: 0x7fc12a9012f0> is supposed to be __lldb_expr_155.VC1"
}
if x is VC2 {
println("\(x) is supposed to be \(VC2.self)")
//"<__lldb_expr_155.VC2: 0x7fc12a900fd0> is supposed to be __lldb_expr_155.VC2"
}
}