Изменить userInfo в функции выбора таймера в Swift

Я хочу обновлять userInfo таймера в функции селектора каждый раз, когда таймер срабатывает.

USERINFO:

var timerDic  = ["count": 0]

Таймер:

Init:     let timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector:     Selector("cont_read_USB:"), userInfo: timerDic, repeats: true)

функция выбора:

public func cont_read_USB(timer: NSTimer)
{
  if var count = timer.userInfo?["count"] as? Int
  {
     count = count + 1

     timer.userInfo["count"] = count
  }
}

Я получаю сообщение об ошибке в последней строке:

"AnyObject? не имеет члена с именем "индекс"

Что здесь не так? В Objective_C эта задача работала с NSMutableDictionary как userInfo

2 ответа

Решение

Чтобы сделать эту работу, объявите timerDic как NSMutableDictionary:

var timerDic:NSMutableDictionary = ["count": 0]

Тогда в вашем cont_read_USB функция:

if let timerDic = timer.userInfo as? NSMutableDictionary {
    if let count = timerDic["count"] as? Int {
        timerDic["count"] = count + 1
    }
}

Обсуждение:

  • Словари Swift являются типами значений, поэтому, если вы хотите обновить его, вам нужно передать объект. Используя NSMutableDictionary вы получаете тип объекта, который передается по ссылке, и его можно изменить, так как это изменяемый словарь.

Полный пример для Swift 4+:

Если вы не хотите использовать NSMutableDictionaryВы можете создать свой собственный class, Вот полный пример с использованием пользовательских class:

import UIKit

class CustomTimerInfo {
    var count = 0
}

class ViewController: UIViewController {

    var myTimerInfo = CustomTimerInfo()

    override func viewDidLoad() {
        super.viewDidLoad()

        _ = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(update), userInfo: myTimerInfo, repeats: true)
    }

    @objc func update(_ timer: Timer) {
        guard let timerInfo = timer.userInfo as? CustomTimerInfo else { return }

        timerInfo.count += 1
        print(timerInfo.count)
    }

}

Когда вы запускаете это в симуляторе, count то, что напечатано, увеличивается каждую секунду.

NSTimer.userInfo имеет тип AnyObject поэтому вам нужно привести его к целевому объекту:

public func cont_read_USB(timer: NSTimer)
{
    if var td = timer.userInfo as? Dictionary<String,Int> {
        if var count = td["count"] {
            count += 1
            td["count"] = count
        }
    }
}
Другие вопросы по тегам