对于Bundle.main.infoDictionary,NSClassFromString返回nil

时间:2017-11-18 03:21:22

标签: ios swift uitabbarcontroller

我正在实现我的UITabBarController programmaticaly,当我尝试从Bundle.main.infoDictionary检索我的控制器时出错![" CFBundleExecutable"]

这是UITabBarController的代码:

import UIKit

class ENTabBarController: UITabBarController {

    override func viewDidLoad() {
        super.viewDidLoad()

        addChildViewControllers()
    }

    fileprivate func addChildViewControllers() {
        addChildViewController("ENSwipeViewController", imageName: "TabBar_swipe_")
        addChildViewController("ENSocialViewController", imageName: "TabBar_social_")
        addChildViewController("ENNotificationViewController", imageName: "TabBar_notification_")

    }

    fileprivate func addChildViewController(_ childControllerName: String, imageName: String) {
        let ns = Bundle.main.infoDictionary!["CFBundleExecutable"] as! String

        let cls: AnyClass? = NSClassFromString(ns + "." + childControllerName)

        let vcClass = cls as! UIViewController.Type
        let vc = vcClass.init()


        vc.tabBarItem.image = UIImage(named: imageName)
        vc.tabBarItem.selectedImage = UIImage(named: imageName + "selected")

        let nav = UINavigationController()
        nav.addChildViewController(vc)
        addChildViewController(nav)
    }
}

错误发生在let vcClass = cls as! UIViewController.Type,并且是:

  

线程1:致命错误:在展开时出乎意料地发现nil   可选值

以下是ENSwipeViewController的简单代码:

import UIKit

class ENSwipeViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        view.backgroundColor = .red
    }
}

2 个答案:

答案 0 :(得分:0)

您的错误是由于尝试强制解包可选值cls而导致的。哪个类型为 AnyObject.type 因此,将以下代码行添加到您的func将解决您的问题。

addChildViewController

let vcClassArray: [UIViewController.Type] = [
    ENSwipeViewController.self
]
let vcClass = classArray[0] // we only have one value 
                        // if you have more you could simply make this a variable
let vc = vcClass.init()

上面的这些行代替了你在同一个函数中所拥有的内容。

let vcClass = cls as! UIViewController.Type
let vc = vcClass.init()

您需要使用AnyClass?

init转换为您要分组的班级和vcClass.init()

答案 1 :(得分:0)

如果你看一下documentation,你会看到它说:

  

返回值

     

由aClassName命名的类对象, ,如果没有该名称的类,则为nil   目前已加载 。如果aClassName为nil,则返回nil。

因此,由于您的ENSwipeViewController尚未加载,因此返回nil ...