【问题标题】:How to call a func without return in Swift? [duplicate]如何在 Swift 中调用函数而不返回? [复制]
【发布时间】:2016-05-05 16:56:08
【问题描述】:

我的班级“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
}

【问题讨论】:

  • 您的 RunnerWindowC 属性是一个隐式展开的可选属性,当您调用该函数时是 nil(应该使用单个 (),而不是双精度) - 请参阅 this Q&A了解更多关于如何安全处理选项的信息。

标签: swift function class call


【解决方案1】:

试试这个:

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

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

【讨论】:

  • 比我得到那个错误:在类型“RunnerWindowController”上使用实例成员“didChangeScreenParameters”
  • 错误:调用中的参数“runnerWindow”缺少参数
  • @Gazzari 尝试编辑答案
  • 我试过了。错误:调用中缺少参数“runnerWindow”的参数:(
【解决方案2】:

一组括号就足够了 - 即。 RunnerWindowC.didChangeScreenParameters()。但是,您遇到的错误可能与 RunnerWindowC 为 nil 有关 - 请确保您分配了 RunnerWindowC(例如,如果您要从中分离,请将其传递)。

【讨论】:

  • 你对“如果你想摆脱它,把它传递”有什么看法?
【解决方案3】:

尝试使用 segue as

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

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

}

【讨论】:

    【解决方案4】:

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

    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(coder:) 方法,而不是 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()
      }
    }
    

    老实说,我不知道两者之间是否存在任何技术差异,而不仅仅是个人喜好。我都用过,没遇到过问题。

    【讨论】:

    • 这里要初始化吗?我收到此错误:该控制器的预期声明没有耦合故事板。
    • 你有什么想法吗?
    • @gazzari 这取决于“其他类”需要如何创建 RunnerWindowController。 RunnerWindowController 是通过 self.presentViewController() 调用的弹出窗口吗?还是通过故事板上的转场显示?还是通过 self.navigationController?.pushViewController() 推送到导航视图控制器?
    • 没有。 AppDelegate 将使用与上述相同的过程调用 RunnerWindowController。它只是一个“类 RunnerWindowControler {很多功能}”。该课程未显示在情节提要上。
    • @Gazzari 好的,那么我将在调用 RunnerWIdowController() 方法的另一个类的 init 函数中对其进行初始化。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-05-23
    • 2020-12-03
    • 1970-01-01
    • 2013-09-17
    • 1970-01-01
    • 2014-03-07
    • 1970-01-01
    相关资源
    最近更新 更多