swift - 如何使用 "#selector"发送参数

标签 swift selector swift4

class TimerFactory {
    var second: Int = 0;
    var timer: Timer = Timer();

    init(second: Int) {
        if(second > 0) {
            self.second = second;
        }
    }

    func runTimer(_ vc: ViewController) -> Void {

        self.timer = Timer.scheduledTimer(timeInterval: 1, target: vc,   selector: (#selector(vc.updateViewTimer)), userInfo: nil, repeats: true)
    }
}


class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()

    }

    @objc func updateViewTimer() {
        print("Hello")
    }
}

extension ViewController {
    @IBAction func startCounter(_ sender: UIBarButtonItem) {
        let timer = TimerFactory(second: 60);
        timer.runTimer(self)
    }
}

很抱歉我的问题我是 SWIFT 的新手但是我想创建计时器但是计时器选择器调用我的 ViewController updateViewTimer 但是这段代码返回 false 但 self.test 工作 这里有什么问题?

最佳答案

您的目标应该是 vc,因为这是计时器将查找方法 updateViewTimer 的地方。

func runTimer(_ vc: ViewController) -> Void {
    self.timer = Timer.scheduledTimer(timeInterval: 1,
                                      target: vc,
                                      selector: (#selector(vc.updateViewTimer)),
                                      userInfo: nil,
                                      repeats: true)
}

当目标是 self 时,它引用 TimerFactory


编辑 (基于评论):

func runTimer(_ vc: ViewController) -> Void {
    self.timer = Timer.scheduledTimer(timeInterval: 1,
                                      target: vc,
                                      selector: (#selector(vc.updateViewTimer(timer:))),
                                      userInfo: self,
                                      repeats: true)
}

@objc func updateViewTimer(_ timer: Timer) {
    if let factory = timer.userInfo as? TimerFactory {
        factory.second -= 1

        print(factory.second)

        if factory.second == 0 {
            print("completed")
            timer.invalidate()
        }
    }        
}

编辑 2 (建议):

如果您计划在另一个类中重用 TimerFactory,那么您需要确保该类中存在 updateViewTimer() 方法,否则代码将崩溃。

相反...我宁愿建议一种更健壮的方法,该方法将使用闭包并放弃对 updateViewTimer(_:) 方法的依赖:

func runTimer(_ vc: ViewController, updateHandler: @escaping (_ second: Int)->Void) -> Void {
    self.timer = Timer.scheduledTimer(withTimeInterval: 1,
                                      repeats: true,
                                      block: { (timer) in
                                        self.second -= 1
                                        updateHandler(self.second)

                                        if self.second == 0 {
                                            timer.invalidate()
                                        }
    })
}

func startCounter() {
    let timer = TimerFactory(second: 10);
    timer.runTimer(self) { (second) in
        print(second)

        if second == 0 {
            print("completed")
        }
    }
}

关于swift - 如何使用 "#selector"发送参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49436223/

相关文章:

jquery - 使用 jQuery 设置选择

swift - Xcode9 是否向后兼容 Swift 3(或 3.1)?

swift - 您如何对具有您不关心的关联值的枚举案例进行简单的在线测试?

ios - Firebase 查询不返回任何数据

ios - 将 [Int64] 的 Swift 数组转换为 NSArray

javascript - jQuery $('element' , this) 选择器,什么意思?

ios - Objective C >> 有没有办法检查 Selector 的返回值?

swift - Swift 4 中的 Smart KeyPaths 无法正常工作

Swift - 从具有长度的 UnsafePointer<UInt8> 转换为 String

swift - 在 UICollectionViewCell 中设置 firebase 值时出现 Nil 可选解包错误