繁体   English   中英

为什么在展开Optional值时此UIAlertController找不到nil?

[英]why does this UIAlertController fail to find nil while unwrapping an Optional value?

我试图通过将View代码与ViewController分开( 请参阅 UIAlertController. )来“ 成为一个好公民 ”,我想知道这是否也可以应用于UIAlertController.代码UIAlertController.

但是,Apple文档

UIAlertController类旨在按原样使用,不支持子类化。 此类的视图层次结构是私有的,不能修改。

尽管我认为它可能仍然是可能的子类UIAlertController -是的,我认识到, UIAlertController不是一个View -所以我想下面的简单测试例子。

该代码包括具有布局约束的子类视图。 UIButton用于激活警报(最终目标操作将成为可以从另一个类调用的函数的基础)。

代码会运行,但是只要按下按钮,Xcode就会在下一行进入调试状态

    self.view.present(alert, animated: true, completion: nil)

与消息

    fatal error: unexpectedly found nil while unwrapping an Optional value
    (lldb) 

我做错了吗? 还是我试图做一些不可能的事情?

ViewController.swift

    import UIKit

    class ViewController: UIViewController {

    var launch: TestView {
    return view as! TestView
    }

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    override func loadView() {
        let contentView                     = TestView(frame: .zero)
        view                                = contentView
    }
}

TestView.swift

import UIKit

class TestView: UIView {

    var view:ViewController!

    override init(frame: CGRect) {
        super.init(frame: frame)
        view.self   = view

        addBehavior()
    }

    convenience init() {
        self.init(frame: CGRect.zero)

    }

    required init(coder aDecoder: NSCoder) {
        fatalError("This class does not support NSCoding")
    }

    func addBehavior() {

        let spacer: UIView                = UIView (frame: .zero)
        spacer.backgroundColor            = UIColor.white

        let view: UIView                = UIView (frame: .zero)
        view.backgroundColor            = UIColor.lightGray
        view.alpha                      = 0.5

        let button: UIButton            = UIButton(frame: .zero)
        button.backgroundColor          = UIColor.blue
        button.setTitleColor(UIColor.white, for: UIControlState.normal)
        button.setTitle("test", for: .normal)
        button.addTarget(self, action: #selector(showExcessNotesAlert), for: .touchUpInside)

        let stackView                   = UIStackView(arrangedSubviews: [spacer, view, button])
        stackView.axis                  = .vertical
        stackView.spacing               = 5
        stackView.translatesAutoresizingMaskIntoConstraints = false

        addSubview(stackView)

        let views                       = ["stackView": stackView]

        var layoutConstraints           = [NSLayoutConstraint]()
        layoutConstraints += NSLayoutConstraint.constraints(withVisualFormat: "|-[stackView]-|", options: [], metrics: nil, views: views)
        layoutConstraints.append(spacer.heightAnchor.constraint(equalToConstant: 30))
        layoutConstraints.append(view.heightAnchor.constraint(equalToConstant: 450))
        layoutConstraints.append(button.heightAnchor.constraint(equalToConstant: 50))
        NSLayoutConstraint.activate(layoutConstraints)

        backgroundColor                 = .white
    }

    func showExcessNotesAlert(_ sender: UIButton) {

        let alert           = UIAlertController(title: "Alert", message: "Grow a brain", preferredStyle: .alert)
        let defaultAction   = UIAlertAction(title: "OK", style: .default, handler: nil)
        alert.addAction(defaultAction)
        self.view.present(alert, animated: true, completion: nil)
    }
}

这里有几个问题,但是可能导致崩溃的原因是此行:

view.self   = view

出于多种原因,这不是有效的代码,但崩溃的原因是您试图访问变量( view ),该变量已定义为隐式展开的可选变量(通过在末尾加上“!”),但是在尝试访问之前,请不要初始化它,因此当然没有用。 最简单的初始化方法是将view.self = view替换为view.self = view self.view = UIViewController() 我不完全了解您要如何使用该view变量,但是进行建议的更改可能会导致崩溃停止。

最终,我在您的代码段中看不到任何代码表明您不应该仅在viewController中使用内置的UIAlertController。 同样,要准确地遵循您希望实现的目标有点困难。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM