【问题标题】:Fatal Error while call method from another class从另一个类调用方法时出现致命错误
【发布时间】:2016-08-04 08:03:01
【问题描述】:

我有两个视图控制器。 我在第一个视图控制器中有一个测试方法如下

class ViewController: UIViewController {

   @IBOutlet weak var myLabel: UILabel!

   override func viewDidLoad() {
       super.viewDidLoad()
       myLabel.hidden = true

   }

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

   func showLabel(){
       myLabel.hidden = false
   }

}

如果我从另一个班级调用 showLabel,它会给我fatal error: unexpectedly found nil while unwrapping an Optional value

另一个viewController如下

class SecondViewController: UIViewController {

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

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

   @IBAction func Save(sender: AnyObject) {
       ViewController().showLabel()
   }
}

如果我从 ViewController 调用 showLabel 方法,它可以正常工作,但如果我从 SecondViewController 调用它,则会出错。

【问题讨论】:

  • ViewController() 创建一个 new ViewController,它永远不会显示在屏幕上

标签: ios swift uiviewcontroller


【解决方案1】:

您的两个视图控制器都使用storyboard/xib;当您在代码中创建此类视图控制器实例时(就像您在 Save 函数中所做的那样),您需要使用 UINib 类或 instantiateViewControllerWithIdentifier 类的 UIStoryboard 方法,因为默认初始化程序(如用于 @987654327 的 init() @) 对 outlet 和 storyboard/xib 相关文件一无所知(outlet 属性myLabel 将始终为零)。

如果您的代码不仅仅是模板,那么您应该重构它,因为在视图控制器中执行未呈现在屏幕上(并且永远不会出现)的 UI 更改没有意义

【讨论】:

【解决方案2】:

这是因为您的标签“myLabel”始终为零。 您的标签是您的第一个 ViewController 的一部分。标签在视图加载时加载。由于 ViewController 视图尚未加载,因此标签也未加载,因此将为 nil

【讨论】:

  • 有什么解决办法?
  • 你的第二个viewcontroller是初始viewController?
  • 不,初始是viewController
  • 您可以为此使用委托或 NSNotification 概念。
  • 我目前的情况没有任何解决方案吗?
【解决方案3】:

你需要使用委托:
1-创建一个具有您计划执行的功能的协议。

protocol ViewControllerDelegate: AnyObject {
  func showLabel()
}

2-在您的SecondViewController 中添加一个委托,其类型为协议ViewControllerDelegate

class SecondViewController: UIViewController {
  weak var delegate: ViewControllerDelegate? // add delegate
  override func viewDidLoad() {
    super.viewDidLoad()
  }

  @IBAction func Save(sender: AnyObject) {
    delegate?.showLabel() // call the method from delegate
  }
}

3-在您的ViewController 中实现ViewControllerDelegate

class ViewController: UIViewController, ViewControllerDelegate {

3-在prepareForSegue 内的第一个视图控制器中设置委托:

class ViewController: UIViewController {

   @IBOutlet weak var myLabel: UILabel!

   override func viewDidLoad() {
       super.viewDidLoad()
       myLabel.hidden = true

   }

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

   func showLabel(){
       myLabel.hidden = false
   }

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if let viewController = segue.destinationViewController as? SecondViewController {
            viewController.delegate = self
        }
    }

}

【讨论】:

  • 还是一样
【解决方案4】:

只需在函数前添加类:

class Math{

    class func addition(numberOne: Int, numberTwo: Int) -> Int{

        var ans: Int = numberOne + numberTwo
        return ans
    }
}

然后你可以像这样从另一个 Swift 类调用它:

Math.addition(40, numberTwo: 2)

将其分配给变量 i:

let i = Math.addition(40, numberTwo: 2) // -> 42

【讨论】:

  • 这个应该去掉,和问题根本没有关系
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-08-02
  • 2019-03-24
  • 2021-08-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多