发送到实例的无法识别的选择器 - Swift 3

unrecognized selector sent to instance - Swift 3

我根据这段代码创建了一个class:https://gist.github.com/etartakovsky/06b8c9894458a3ff1b14

当我尝试实例化 class 并调用 tick 方法时,出现 "unrecognized selector sent to instance" 错误。我一遍又一遍地检查了代码,但不明白为什么会这样,欢迎任何建议:

秒表Class来源:

import Foundation
import QuartzCore

class StopWatch: NSObject{

    private var displayLink: CADisplayLink!
    private let formatter = DateFormatter()

    var callback: (() -> Void)?
    var elapsedTime: CFTimeInterval!

    override init() {
        super.init()

        self.displayLink = CADisplayLink(target: self, selector: "tick:")
        displayLink.isPaused = true
        displayLink.add(to: RunLoop.main, forMode: RunLoopMode.commonModes)

        self.elapsedTime = 0.0

        formatter.dateFormat = "mm:ss,SS"
    }
    convenience init(withCallback callback: @escaping () -> Void) {
        self.init()
        self.callback = callback
    }
    deinit {
        displayLink.invalidate()
    }

    func tick(sender: CADisplayLink) {
        elapsedTime = elapsedTime + displayLink.duration
        callback?()
    }

    func start() {
        displayLink.isPaused = false
    }

    func stop() {
        displayLink.isPaused = true
    }

    func reset() {
        displayLink.isPaused = true
        elapsedTime = 0.0
        callback?()
    }

    func elapsedTimeAsString() -> String {
        return formatter.string(from: Date(timeIntervalSinceReferenceDate:elapsedTime))
    }

}

这里是 ViewController 代码:

import UIKit

class ActivityViewController: UIViewController {

    let stopwatch = StopWatch()

    @IBOutlet weak var elapsedTimeLabel: UILabel!

    func tick() {
        elapsedTimeLabel.text = stopwatch.elapsedTimeAsString()
    }

    override func viewDidLoad() {

        super.viewDidLoad()
        tick()
        stopwatch.callback = self.tick
        stopwatch.start()


        // Do any additional setup after loading the view.
    }

}

在Swift 3中使用#selector语法

self.displayLink = CADisplayLink(target: self, selector: #selector(tick))

在 Swift 4 中,您还必须在操作的开头插入 @objc

@objc func tick(...

尝试两件事。使用 Swift 3:

引入的新的(更安全的)选择器语法
CADisplayLink(target: self, selector: #selector(tick(sender:)))

并确保将您的 tick 方法公开给 Objective-C(rules have changed in Swift 4):

@objc func tick(sender: CADisplayLink) {
    ...
}

要说清楚:unrecognized selector sent to instanceMessagePassing 场景中的一个错误,这意味着所需的选择器是:

func tick(sender: CADisplayLink) {...}

并且已经收到无法识别的消息。 寻址错误,找不到

正如其他成员所说,您必须通过添加 #selector(tick):

来更改目标选择器

self.displayLink = CADisplayLink(target: self, selector: #selector(tick))

您可以在此 thread

中找到有关该错误的更多详细信息