2016-12-26 3 views
4

Я пытаюсь сделать приложение в Swift на моем Ubuntu (Ubuntu 15.10 wily, Swift swift-3.0.1-RELEASE), используя Perfect library.Swift 3 Linux with Perfect: добавьте запланированный таймер с интервалом в runLoop

Я хотел бы иметь функцию, называемую каждые X секунд. Для этого я использую Timer class of the Foundation module:

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") 
    } 
} 

Несмотря найти несколько решений, с помощью этого кода, компиляция не удалась:

$> 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) { 

Другая ошибка компиляции, если я простирающийся мой класс от NSObject или если Я удалил аргумент 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) 

Я пытался использовать другие декларации, которые не используют селекторы:

class MyTimer { 
    init() { 
     print("MyTimer.init") 
     var timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { 
      timer in 
      print("MyTimer.onTimer") 
     } 
    } 
} 

Сборник работает, но мой второй отпечаток никогда не вызывается. Я также попытался вручную добавить свой таймер на текущее RunLoop:

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() 
    } 
} 

Никогда называемый снова (и timer.fire() вызывать только один раз моя функция). И, наконец:

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)) 
    } 
} 

Мое сообщение "MyTimer.onTimer" печатается 5 раз, но мой сервер (с помощью Совершенная библиотеки) начинается только в конце:

$> 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 

Я больше не знаю что попробовать. Это может быть проблемой для библиотеки Perfect, но я не могу найти ничего, чтобы решить мои проблемы. Возможно, я могу запустить новый поток и запустить в нем таймер, но он немного сложнее?

ответ

4

Если вы серьезно используете Perfect, пожалуйста, не используйте материал Foundation. Попробуйте Совершенная резьб: 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 

это безопасно и просто
очень типична стороне сервера кодирования

+0

Большое спасибо. Это потрясающе. :) –

+0

@PerfectlyRock Как я могу повторить Threading.dispatch {}? –

+0

Я не уверен, о чем вы говорили. Вы можете либо Threading.dispatch {forloop(), либо whileloop()} или, альтернативно, создать функцию() {Threading.dispatch {}}, а затем для _ в 0 ... 10 {function()} – PerfectlyRock

Смежные вопросы