在 Swift 中更改计时器选择器函数中的 userInfo

Posted

技术标签:

【中文标题】在 Swift 中更改计时器选择器函数中的 userInfo【英文标题】:Change userInfo in timer selector function in Swift 【发布时间】:2014-11-02 10:50:57 【问题描述】:

我想在每次定时器触发时更新选择器函数中定时器的用户信息。

用户信息:

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

【问题讨论】:

【参考方案1】:

要完成这项工作,请将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 每秒都会增加。

【讨论】:

@AdrianBartholomew,我刚刚在一个带有 Xcode 9.2(最新)和 Swift 4 的应用程序中尝试了这个,它工作正常。我不得不使用Timer 而不是NSTimer 并将@objc 添加到计时器更新功能中,但它起作用了。你有什么症状? 如果我在 userInfo 中传递一个布尔值,它在调用函数时总是为假。 @ChewieTheChorkie,你是直接传递一个布尔值,还是一个类的属性?定时器例程会改变布尔值吗? 我不想也做那个类属性,所以我只是通过了直接的布尔值。 @ChewieTheChorkie,Bool 是一种值类型,因此它始终只是初始值。您需要传递一个包装 Bool 的对象。【参考方案2】:

NSTimer.userInfoAnyObject 类型,因此您需要将其强制转换为目标对象:

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
        
    

【讨论】:

但请注意,这只会修改本地的 td 字典,而不是 timerDic 属性(因此 每个 调用的计数为零) @MartinR:你说得对,这里需要传递对timerDic 属性的引用。最好修改属性对象本身。

以上是关于在 Swift 中更改计时器选择器函数中的 userInfo的主要内容,如果未能解决你的问题,请参考以下文章

在按钮目标 Swift 的选择器方法中更改两个对象

在 Swift 上更改选择器视图的颜色

swift iOS - Swift - 显示图库/相机的图像选择器,感谢http://www.theappguruz.com/blog/user-interaction-camera-using

swift iOS - Swift - 显示图库/相机的图像选择器,感谢http://www.theappguruz.com/blog/user-interaction-camera-using

swift iOS - Swift - 显示图库/相机的图像选择器,感谢http://www.theappguruz.com/blog/user-interaction-camera-using

swift iOS - Swift - 显示图库/相机的图像选择器,感谢http://www.theappguruz.com/blog/user-interaction-camera-using