【问题标题】:Swift 3 Linux with Perfect: Add a scheduled timer with interval to the runLoopSwift 3 Linux with Perfect:向 runLoop 添加一个带间隔的计划计时器
【发布时间】:2017-05-10 18:50:52
【问题描述】:

我正在尝试使用Perfect library 在我的 Ubuntu(Ubuntu 15.10 wily,Swift swift-3.0.1-RELEASE)上使用 Swift 制作应用程序。

我希望每 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 次,但我的服务器(使用 Perfect 库)仅在最后启动:

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

我不知道该尝试什么了。完美库可能有问题,但我找不到任何东西可以解决我的后顾之忧。我也许可以运行一个新线程,并在其中启动我的计时器,但这有点复杂?

【问题讨论】:

    标签: swift timer swift3 nsrunloop perfect


    【解决方案1】:

    如果您认真使用 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
    

    安全又简单
    非常典型的服务器端编码

    【讨论】:

    • 非常感谢。太棒了。 :)
    • 我不确定你在说什么。您可以使用 Threading.dispatch { forloop() 或 whileloop() } 或者创建一个 function() { Threading.dispatch {} } 然后 for _ in 0 ... 10 { function() }
    • 我尝试使用此代码进行部署,显然需要将import GlibC 升级到import SwiftGlibc。然后这很顺利。我在其他地方找到的一个例子:github.com/PerfectlySoft/Perfect-NewRelic-Linux/commit/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多