IBOutlet是ViewControllers的nil Xcode 7

时间:2015-11-26 08:25:53

标签: xcode swift macos

当我创建一个新的NSVC子类并向其添加一些IBOulets时,当我尝试访问它们时它们总是为零。我尝试创建一个新项目,只有一个VC类,只有一个Outlet,它仍然是零。

我已经检查过它们确实是连接的。我尝试用完整的笔尖名称实例化该类。我还清理了项目,并删除了派生数据。没有任何区别。

那么可能导致这种情况呢?它正在讨论所有新项目;我为我的旧项目添加了新的插座,它们工作正常。所有的IBOutlets都是零,而不仅仅是少数几个。我在Xcode 7.1.1上。

我得到的错误是:

  

致命错误:在解包可选值时意外发现nil

2 个答案:

答案 0 :(得分:1)

如果其他人遇到类似的问题,我找到了解决方法。 IBOutlet是零,因为它的超级视图从未加载过,因此应用程序从未创建它。一个简单的黑客就是在使用任何子视图之前写这个:

let view = viewController.view

这会创建视图,因此它上面有所有插座。

P.S。我知道这不是一个真正的解决方案,但我想不出另一个。如果有人有任何建议,请随时发布。

答案 1 :(得分:0)

我的猜测是,您尝试在加载视图之前尝试访问init方法中的outlet,或者在设置值时从访问器访问。处理这种情况有两种方法。

第一种是推迟更新子视图,直到您知道视图已加载为止。我通过从updateView()调用viewWillAppear()方法来完成此操作。我通常在变量变化时调用此方法,因此我测试以确保在继续之前视图已加载。如果视图尚不存在,则设置视图没有任何价值。它看起来像这样:

class MyViewController: UIViewController {

    var product: Product {
        didSet {
            updateView()
        }
    }

    @IBOutlet private weak var productNameLabel: UILabel!

    override func viewWillAppear(animated: Bool) {
        super.viewWillAppear(animated)
        updateView()
    }

    private func updateView() {
        guard isViewLoaded() else {
            return
        }

        if let product = product {
            productNameLabel.text = product.title
        }
    }
}

另一个与您正在执行的操作类似的选项是强制视图提前加载。我认为这不太可取,但在某些情况下,这是正确的方法。但不是按照你发现的方式去做,而是更有意地这样做:

class MyViewController: UIViewController {

    var product: Product {
        didSet {
            loadViewIfNeeded()
            productNameLabel.text = product.title
        }
    }

    @IBOutlet private weak var productNameLabel: UILabel!
}