2016-05-05 5 views
0

Ich habe diese Funktion in meiner Klasse "RunnerWindowController":Wie man eine Funktion ohne Rückkehr in Swift anruft?

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

Ich versuche, mit der Funktion aus einer anderen Klasse zu nennen:

var RunnerWindowC: RunnerWindowController! 

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

ich diesen fatalen Fehler:

fatal error: unexpectedly found nil while unwrapping an Optional value 

Ich brauche keine Rückkehr, nur die Ausführung der Funktion.

EDIT: 05/13/2016

Keine der Antworten helfen, weil ich eine INIT in sterben RunnerWindowController haben.

gelöstes Problem:

löste ich das Problem mit einem 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

Ihre 'RunnerWindowC' Eigenschaft ist ein implizit ungeöffneten optional und ist' nil', wenn Sie die Funktion (die nennen sollte mit einem einzigen '()', nicht ein Doppel) - siehe [diese Q & A] (http://stackoverflow.com/questions/32170456/what-does-fatal-error-unexpectedly-found-nil-while-unwrapping) -an-optional-value) für weitere Informationen zum sicheren Umgang mit Optionals. – Hamish

Antwort

0

Ein Satz von Klammern ist genug - das heißt. RunnerWindowC.didChangeScreenParameters(). Der Fehler, den du bekommst, hat wahrscheinlich damit zu tun, dass RunnerWindowC kein Nil ist - vergewissere dich, dass du RunnerWindowC zugeteilt hast (zB wenn du davon weggehst, gib es weiter).

+0

was machst du mit "wenn du davon abstehst, gib es weiter"? – Gazzari

0

Das Problem ist wahrscheinlich, dass Sie versuchen, eine Methode für eine Variable aufzurufen, die nicht initialisiert wurde. Der Code, den Sie angezeigt haben, wird nur die Klassenvariable definieren und nicht initialisieren. An einem gewissen Punkt, bevor diese Methode aufrufen werden Sie es wie folgt initialisieren müssen:

self.RunnerWindowC = RunnerWindowController() 

Wenn das Controller mit einem Storyboard gekoppelt ist, Sie es wie folgt initialisieren:

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

EDIT 5-12 -16:

Um eine Variable auf Klassenebene in schnellen Initialisierung gibt es zwei Ansätze:

Ansatz A:

Bitte beachten Sie, dass der von Ihnen implementierte Initialisierer von abhängt, von welcher Klasse Sie erben. Wenn Sie nicht von einer Klasse erben oder von NSObject erben (wie ich unten), dann überschreiben Sie init() Wenn Sie von einer anderen Klasse erben, müssen Sie möglicherweise einen anderen Initiator überschreiben. Wenn Sie beispielsweise von UIViewController erben, sollten Sie die Methode init (Coder :) überschreiben, nicht 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() 
    } 
} 

Ansatz B:

Swift können Sie auch die Variablen initialisieren, wenn sie auch in der Klasse definiert sind, so können Sie dies auch tun:

class MyParentClass: NSObject { 
    var RunnerWindowC = RunnerWindowController() 

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

ich ehrlich don Ich weiß nicht, ob es zwischen den beiden einen anderen technischen Unterschied als nur persönliche Vorlieben gibt. Ich habe beide benutzt und hatte nie ein Problem.

+0

Wehere muss es initialisieren? Ich bekomme diesen Fehler: Erwartete Deklaration Bei diesem Controller ist kein Storyboard gekoppelt. – Gazzari

+0

Haben Sie eine Idee? – Gazzari

+0

@gazzari hängt davon ab, wie diese "andere Klasse" den RunnerWindowController erstellen muss. Ist das RunnerWindowController ein Popup, das über self.presentViewController() aufgerufen wird? Oder wird es über einen Abschnitt auf deinem Storyboard angezeigt? Oder wird es über self.navigationController? .pushViewController()? – JiuJitsuCoder

1

versuchen Sie dies:

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

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

als ich diesen Fehler erhalte: Verwendung des Instanzmitglieds 'didChangeScreenParameters' auf dem Typ 'RunnerWindowController' – Gazzari

+0

Fehler: Fehlendes Argument für Parameter 'RunnerWindow' im Aufruf – Gazzari

+0

@Gazzari versuchen Antwort bearbeiten – iParesh

0

Versuch mit segue zu verwenden, wie

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

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

} 
Verwandte Themen