2016-12-26 1 views
4

Ich versuche, eine Anwendung in Swift auf meinem Ubuntu (Ubuntu 15.10 schlau, Swift swift-3.0.1-RELEASE) mit der Perfect library.Swift 3 Linux mit Perfect: Fügen Sie einen Zeitplan Timer mit Intervall zum runLoop

Ich möchte jede X Sekunde eine Funktion aufgerufen haben. Dafür bin ich die Timer class of the Foundation module mit:

class MyTimer { 
    init() { 
     var timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(MyTimer.onTimer(timer:)), userInfo: nil, repeats: true) 
    } 
    @objc func onTimer(timer: Timer) { 
     print("MyTimer.onTimer") 
    } 
} 

Trotz mehrerer Lösungen mit diesem Code zu finden, scheiterte die Zusammenstellung:

$> swift build 
Compile Swift Module 'my-app' (7 sources) 
/home/.../Sources/MyTimer.swift:8:16: error: method cannot be marked @objc because the type of the parameter cannot be represented in Objective-C 
    @objc func onTimer(timer: Timer) { 

Ein weiterer Übersetzungsfehler, wenn ich Verlängerung meiner Klasse von NSObject oder wenn ich entfernte das Argument timer:

$> swift build 
Compile Swift Module 'my-app' (7 sources) 
/home/.../Sources/MyTimer.swift:6:83: error: '#selector' can only be used with the Objective-C runtime 
    var timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(MyTimer.onTimer), userInfo: nil, repeats: true) 

ich versuchte, die andere Erklärung zu verwenden, die Wähler nicht verwenden:

Die Kompilierung funktioniert, aber mein zweiter Druck wird nie aufgerufen. Ich habe auch versucht manuell meine Timer zum aktuellen RunLoop hinzufügen:

class MyTimer { 
    init() { 
     print("MyTimer.init") 
     var timer = Timer(timeInterval: 1, repeats: true) { 
      timer in 
      print("MyTimer.onTimer") 
     } 
     RunLoop.current.add(timer, forMode: .defaultRunLoopMode) 
     // timer.fire() 
    } 
} 

Nie wieder genannt (und timer.fire() nur einmal meine Funktion aufrufen). Und schließlich:

class MyTimer { 
    init() { 
     print("MyTimer.init") 
     let timer = Timer(timeInterval: 1, repeats: true) { 
      timer in 
      print("MyTimer.onTimer") 
     } 
     RunLoop.current.add(timer, forMode: .defaultRunLoopMode) 
     RunLoop.current.run(until: Date(timeIntervalSinceNow: 4.0)) 
    } 
} 

Meine Nachricht "MyTimer.onTimer" 5 mal gedruckt, aber mein Server (die perfekte Bibliothek) gestartet werden erst am Ende:

$> swift build && ./.build/debug/my-app 8400 
Compile Swift Module 'my-app' (7 sources) 
Linking ./.build/debug/my-app 
MyTimer.init 
MyTimer.onTimer 
MyTimer.onTimer 
MyTimer.onTimer 
MyTimer.onTimer 
MyTimer.onTimer 
[INFO] Starting HTTP server on 0.0.0.0:8181 

Ich weiß nicht mehr, was zu versuchen. Es kann ein Problem mit der perfekten Bibliothek sein, aber ich kann nichts finden, was meine Sorgen lösen könnte. Ich kann vielleicht einen neuen Thread starten und meinen Timer starten, aber es wird ein bisschen komplex?

Antwort

4

Wenn Sie Perfect ernsthaft verwenden, verwenden Sie bitte nicht Foundation-Zeug. Versuchen Sie Perfekt Threading: http://www.perfect.org/docs/thread.html

import PerfectThread 
#if os(Linux) 
import GlibC 
#else 
import Darwin 
#endif 

Threading.dispatch { 
    sleep(10) // wait for 10 seconds 
    doSomething() 
}//end threading 

es sicher und einfach ist
sehr typische Server-Seite Codierung

+0

Thank you very much. Dies ist perfekt. :) –

+0

@PerfectlyRock Wie kann ich Threading.dispatch {} wiederholen? –

+0

Ich bin mir nicht sicher, worüber du geredet hast. Sie können entweder Threading.dispatch {forloop() oder whileloop()} oder alternativ eine Funktion() {Threading.dispatch {}} und dann für _ in 0 ... 10 {function()} – PerfectlyRock