如何阻止 NSTimer 转到 Selector 并以另一种方法扩展它?

How to stop NSTimer from going to Selector and extend it in another method?

我正在从 BLE 设备读取 RFID 标签。如果我读取一个特定的 RFID 值,我不想在下一秒读取相同的值。为此,我将该值保存在一个数组中,并在计时器完成一秒后将其删除。

{

func peripheral(peripheral: CBPeripheral, didUpdateValueForCharacteristic characteristic: CBCharacteristic, error: NSError?){

let rfid = (characteristic.value?.description.capitalizedString)!

 if readRfids.containsObject(rfid){
     if timer.valid{
         self.timer = NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: #selector(self.timeEnd(_:)), userInfo: nil, repeats: false)
     }
 }else{
     timer.invalidate()
 }

if !timer.valid && !readRfids.containsObject(rfid){
   readRfids.addObject(rfid)
   self.timer = NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: #selector(self.timeEnd(_:)), userInfo: nil, repeats: false)
}

}

func timeEnd(sender: Selector){
    if !timer.valid{
        readRfids.removeLastObject()
    }else{
        print(timer.fireDate)
    }
}

我面临的问题是 timeEnd(_:) 在一秒后被多次调用,而 readRfids.removeLastObject() 从未被调用。 我的 BLE 设备在一秒钟内发送通知超过 10 次。如果它是不同的 rfid,我想读取值,如果读取相同的 rfid,我想将计时器再延长一秒钟。 timer.fireDate 一秒后开始打印,打印时间等于来自 BLE 设备的通知。

您正在安排多个计时器,因为您说 如果 timer.valid 则安排一个计时器。另外,我认为只要稍作改动,您就可以让您的代码暂时忽略多个项目

类似于:

var readRfids = [String:Double]()
var timer: NSTimer

Somewhere like `init` or `viewDidLoad`

    self.timer = NSTimer.scheduledTimerWithTimeInterval(0.1, target: self, selector: #selector(self.timeEnd(_:)), userInfo: nil, repeats: true)

func peripheral(peripheral: CBPeripheral, didUpdateValueForCharacteristic characteristic: CBCharacteristic, error: NSError?){

    if let rfid = (characteristic.value?.description.capitalizedString) {
        if self.readRfids[rfid] == nil {
            //Not seen recently, so process this object
        }
        self.readRfids[rfid] = 1.0
    } 
}

func timeEnd(sender: Selector){
    for (rfid, remaining) in self.readRfids {
        remaining = remaining - 0.1
        if (remaining > 0) {
            self.readRfids[rfid] = remaining
        } else {
            self.readRfids[rfid] = nil
        }
    }
} 

当看到一个项目时,它被放入字典中,计数为 1。计时器每十分之一秒计时并递减每个计数。当计数为 0 时,该项目将从字典中删除。这确保每个项目自被看到后仅在字典中保留 1 秒。