如何在Swift结构上调用基于选择器的Timer方法?

时间:2017-05-23 21:58:10

标签: swift

这很有趣:看起来您无法在快速struct上调用选择器消息!我的意思是这样的:我有一个struct,想要在其上实现一个简单的Timer,使用带有Timer.scheduledTimer参数的selector:变体。编译器告诉我,被调用的选择器方法需要一个objc属性来使该方法对Objective-C调用序列可见,但是不支持(另一个有用的编译器消息!;-) for非类对象。

我认为在我的特定情况下使用struct是一种更好的方法,但我想我必须将其反向移植到class,除非有人拥有更好的主意...

1 个答案:

答案 0 :(得分:1)

我知道这是一个老问题,但是正如其他人在评论中指出的那样,这不可能直接实现。

通过在Timer内将计时器逻辑隔离到struct中,可以在class内创建Swift struct。总体规划如下。

  1. Timer逻辑隔离到class中的struct中。
  2. 传递包含的struct(或class中的其他struct实例)作为传达倒计时计时器的一种方式。
  3. 实例化逻辑class,并存储对其的引用,直到需要为止。

请参见下面的代码示例。

struct MyStruct{
    
    var timerLogic: TimerLogic!

    class TimerLogic{
        var structRef: MyStruct!
        var timer: Timer!

        init(_ structRef: MyStruct){
            self.structRef = structRef;
            self.timer = Timer.scheduledTimer(
                timeInterval: 2.0,
                target: self,
                selector: #selector(timerTicked),
                userInfo: nil,
                repeats: true)
        }

        func stopTimer(){
            self.timer?.invalidate()
            self.structRef = nil
        }

        @objc private func timerTicked(){
            self.structRef.timerTicked()
        }
    }

    func startTimer(){
        self.timerLogic = TimerLogic(self)
    }    

    func timerTicked(){
         print("Timer tick notified")

         // Stop at some point
         // timerLogic.stopTimer()
         // timerLogic = nil
    }
}