Swift - NSTimer 为 userInfo 参数传递了错误的值

Swift - NSTimer passing wrong value for userInfo param

我最近开始学习 Swift 编程语言,我喜欢它。为了帮助我学习,我一直在使用 XCode 7 开发几个简单的应用程序。其中一个应用程序是手电筒,其中一个功能是频闪灯。我决定使用 NSTimer class 来安排在设定的时间间隔调用手电筒切换功能,从而提供不错的频闪效果。我第一次破解定时器代码如下:-

NSTimer.scheduledTimerWithTimeInterval(0.5, target: self.torch, selector: "toggleTorch:", userInfo: false, repeats: true)

正如您在此处看到的,我正在使用自己定制的 Torch 对象来处理闪光灯切换功能。我将指定为实例变量的 torch 对象作为目标参数传递,然后在 Torch class 中调用以下函数,我将其作为选择器传递:-

func toggleTorch(adjustingBrightness: Bool) -> Bool {
    let device = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)

    defer {
        device.unlockForConfiguration()
    }

    guard device.hasTorch else {
        return false
    }
    do {
        try device.lockForConfiguration()

        if  !adjustingBrightness && device.torchMode == AVCaptureTorchMode.On {
            device.torchMode = AVCaptureTorchMode.Off
        }
        else if !adjustingBrightness && device.torchMode == AVCaptureTorchMode.Off {
            try device.setTorchModeOnWithLevel(brightnessLevel)
        }               
        else if adjustingBrightness && device.torchMode == AVCaptureTorchMode.On {
            try device.setTorchModeOnWithLevel(brightnessLevel)
        }
    } catch {
        return false
    }

    return true
}

我遇到的问题是,当计时器调用 toggleTorch 方法时,它将 true 的值作为参数传递,即使我已经明确地将 false 传递给计时器作为 userInfo 参数。

所以我挠头想"Ah"让我们尝试在selector/method参数中使用默认值false并在定时器[=20]中传递nil =] 参数。这样我就可以依赖每次调用的 false 的默认值。所以我的新选择器签名如下所示:-

func toggleTorch(adjustingBrightness: Bool = false) -> Bool

现在调用它的计时器已更改为:-

NSTimer.scheduledTimerWithTimeInterval(0.5, target: self.torch, selector: "toggleTorch:", userInfo: nil, repeats: true)

然而,尽管有默认参数并且没有参数通过计时器传递,传递的值仍然是 true。因此,我进行了更多修改,并决定看看使用我的 ViewController 作为目标对象是否会有所作为。我在 ViewController 中放置了一个新的选择器,如下所示:-

func toggleTorch() {
    torch.toggleTorch(false)
}

然后我更新我的计时器以在 ViewController 中调用这个新方法:-

NSTimer.scheduledTimerWithTimeInterval(0.5, target: self, selector: "toggleTorch", userInfo: nil, repeats: true)

'Hey Presto' 它现在工作正常并且正在传递 false 的正确布尔值,因为我自己传递了该值。为什么会这样?有关信息,我已经学习 Swift 大约三个星期了,所以我不是专家

NSTimer 不会将 userInfo 信息作为参数传递给选择器。它将自身作为参数传递,以便您知道调用了哪个计时器。

你应该设置如下:

NSTimer.scheduledTimerWithTimeInterval(0.5, target: self.torch, selector: "strobeTimerFired:", userInfo: nil, repeats: true)

并且在你的 Torch 对象中有如下方法:

func strobeTimerFired(timer: NSTimer) {
    toggleTorch(false)
}

在这种情况下,您不需要在 strobeTimerFired 方法中访问计时器对象,但最好还是包含它(可以跳过)。例如,您可以添加额外的检查以确保触发该方法的计时器是您预期的计时器。

如果您确实需要将 userInfo 用于某事(在这种情况下您认为不需要它),您可以在原始 scheduledTimerWithTimeInterval 调用中传递一个对象作为userInfo 参数,然后您将在 strobeTimerFired 方法中访问该参数,方法是:timer.userInfo.