2016-08-06 17 views
2

Ich habe eine Funktion in einer anderen Funktion. in function1 mag ich NSTimer nennen func2 nach einiger Zeit wie folgt verwenden:Übergeben einer Swift-Funktion an NSTimer

func myFunc1() 
{ 
    NSTimer.scheduledTimerWithTimeInterval(1, target: ??, selector:#selector(myFunc2()), userInfo: nil, repeats: false) 
    func myFunc2() 
    { 
     // do something... 
    } 
} 

Was ist der richtige „Ziel“ Wert, den ich dort passieren soll? ist es überhaupt möglich?

+0

Sie können dies nicht tun, myFunc2 als eine Klassenmethode –

+0

@DanielKrom, meinst du _instance Methode auf der obersten Ebene in der Klasse_ (oder so ähnlich), vielleicht? – holex

+0

@holex Ja, vergessen, dass Klassenmethode bedeutet hier statische –

Antwort

4

Wenn Sie vor iOS 10 zielen, können Sie keine Funktion an NSTimer übergeben, da zu diesem Zeitpunkt keine API zur Unterstützung von Abschlussrückrufen eingeführt wurde.

iOS 10 und später Ansatz

// swift 2.x users should still use NSTimer instead 
Timer.scheduledTimer(withTimeInterval: 2.0, repeats: true) { timer in 
    // ... 
} 

generalistischen Ansatz

Sie diese Klasse hinzufügen können, und es jederzeit wieder verwenden:

final class TimerInvocation: NSObject { 

    var callback:() ->() 

    init(callback: @escaping() ->()) { 
     self.callback = callback 
    } 

    func invoke() { 
     callback() 
    } 
} 

extension Timer { 

    static func scheduleTimer(timeInterval: TimeInterval, repeats: Bool, invocation: TimerInvocation) { 

     Timer.scheduledTimer(
      timeInterval: timeInterval, 
      target: invocation, 
      selector: #selector(TimerInvocation.invoke(timer:)), 
      userInfo: nil, 
      repeats: repeats) 
    } 
} 

Mit dieser Klasse können Sie tu das jetzt einfach:

let invocation = TimerInvocation { 
    /* invocation code here */ 
} 

NSTimer.scheduledTimerWithTimeInterval(1, target: invocation, selector:#selector(TimerInvocation.invoke), userInfo: nil, repeats: false) 

Sie nicht über die Beibehaltung der invocation Variable kümmern müssen, da sie durch NSTimer

+1

Sie sind der MANN! :) –

+0

Dies weist auf eine offene Frage hin. Wird Swift eine schöne, saubere, moderne Swift-ähnliche Timerfunktion als Teil seiner Standardbibliothek haben? Es sollte eine Schließung als Parameter nehmen. Die Dispatch-Klasse in Swift 3 ist in der Nähe ... –

+1

@DuncanC Yeah, Foundation Framework sowie andere werden sich langsam aber sicher an Swift im Laufe der Zeit anpassen. Fürs Erste ist das Beste, was Sie tun können, dünne Wrapper zu schreiben, um Ihre Swift-Entwicklung zu vereinfachen. Wenn die neuen APIs herauskommen, wird das Entfernen unnötiger Abhängigkeiten einfach. Schauen Sie sich zum Beispiel [kitz] (http://kitz.io) an. Es umschließt 'NSNotificationCenter', so dass Sie Closures passieren können. – Mazyod

3

In Swift 3, die neue Timer hat eine Factory-Methode, die nimmt einen Verschluss gehalten wird:

Timer.scheduledTimer(withTimeInterval: TimeInterval, repeats: Bool, block: (Timer) -> Void) 

In Ihrem Fall könnten Sie es wie folgt mit folgender abschließender Closure-Syntax aufrufen:


Hinweis: Dies ist nur in iOS 10 oder neuer verfügbar.

+0

Aber das funktioniert nicht in iOS9, richtig? – Fattie

+1

@JoeBlow, korrekt. Dies wurde in iOS10 verfügbar. – vacawama

+0

Perfekte Infos, danke. – Fattie