如何在Swift中无需返回时调用func?

时间:2016-05-05 16:56:08

标签: swift function class call

我在班上有这个功能" RunnerWindowController":

func didChangeScreenParameters(){
    runnerLayer.removeAllAnimations()
    animateRunner()
}

我尝试使用以下方法从另一个类中调用该函数:

var RunnerWindowC: RunnerWindowController!

@IBAction func btnSenden(sender: AnyObject) {
    RunnerWindowC.didChangeScreenParameters()
}

我得到了这个致命的错误:

fatal error: unexpectedly found nil while unwrapping an Optional value

我不需要任何回报,只需执行该功能。

编辑:2016年5月13日

没有一个答案有帮助,因为我在RunnerWindowController中有一个INIT。

已解决的问题:

我用NSTimer解决了这个问题。

RunnerWindowController:

var SetDidChange : Bool = false

class RunnerWindowController{
var startvalue : CGFloat = 0

var timer : NSTimer?

func initTimer() {
    self.timer = NSTimer.scheduledTimerWithTimeInterval(1, target:
self, selector: #selector(refresh), userInfo: nil, repeats: true)
}

@objc func refresh() {
    if (SetDidChange == true) {
        print("Refresh done")
        runnerLayer.removeAllAnimations()
        animateRunner()
        SetDidChange = false
    }
}
....
}

RunnerPrefController:

    override func viewDidAppear() {
    SetDidChange = false
}

@IBAction func btnSenden(sender: AnyObject) {
    SetDidChange = true
}

4 个答案:

答案 0 :(得分:1)

试试这个:

class RunnerWindowController: UIViewController {
    class func didChangeScreenParameters(){
        runnerLayer.removeAllAnimations()
        animateRunner()
    }
}

class yourClassName: UIViewController {
    @IBAction func btnSenden(sender: AnyObject) {
        RunnerWindowController().didChangeScreenParameters()
    }
}

答案 1 :(得分:0)

一组括号就足够了 - 即。 RunnerWindowC.didChangeScreenParameters()。但是,你得到的错误可能与RunnerWindowC为零有关 - 请确保你指定RunnerWindowC(例如,如果你偏离它,传递它)。

答案 2 :(得分:0)

问题可能是您尝试在尚未初始化的变量上调用方法。您显示的代码仅定义类变量,而不是初始化它。在调用该方法之前的某个时刻,您必须像这样初始化它:

self.RunnerWindowC = RunnerWindowController()

如果该控制器耦合到故事板,您可以像这样初始化它:

let storyboard = UIStoryboard(name: "NameOfStoryboardFile", bundle: nil)
self.RunnerWindowC = storyboard.instantiateViewControllerWithIdentifier("RunnerWindowController") as! RunnerWindowController

编辑5-12-16:

要在swift中初级化类级别的变量,有两种主要方法:

方法A:

请注意,您实施的初始化程序将取决于 你从哪个班继承。如果你不从任何班级或你继承 从NSObject继承(就像我在下面做的那样)然后你将覆盖init() 如果从其他类继承,则可能必须覆盖其他类 初始化。例如,从UIViewController继承意味着你应该 覆盖init(编码器:)方法,而不是init()。

class MyParentClass: NSObject {
  var RunnerWindowC: RunnerWindowController!

  init() {
    RunnerWindowC = RunnerWindowController()
    super.init()
    // ^^^ All class variables need to be initialized
    // before the call to super.init() in swift!
  }

  // If you were doing this in a class that inherits UIViewController
  // you would implement the initializer like this instead:
  /****
  required init?(coder aDecoder: NSCoder) {
    RunnerWindowC = RunnerWindowController()
    super.init(coder: aDecoder)
  }
  ****/

  @IBAction func btnSenden(sender: AnyObject) {
    self.RunnerWindowC.didChangeScreenParameters()
  }
}

方法B:

Swift还允许您在类级别定义变量时对其进行初始化,因此您也可以这样做:

class MyParentClass: NSObject {
  var RunnerWindowC = RunnerWindowController()

  @IBAction func btnSenden(sender: AnyObject) {
    self.RunnerWindowC.didChangeScreenParameters()
  }
}

老实说,我不知道除了个人偏好之外,两者之间是否存在任何技术差异。我已经使用了两者,从未遇到过问题。

答案 3 :(得分:0)

尝试使用segue作为

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {

 let vc  = segue.destinationViewController as? RunnerWindowController
 vc?.didChangeScreenParameters()

}