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

时间:2016-01-01 19:33:07

标签: ios swift2 nstimer

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

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

正如你在这里看到的,我使用自己定制的Torch对象来处理flash切换功能。我将我指定的火炬对象作为实例变量作为目标参数传递,然后在Torch类中调用以下函数,我将其作为选择器传递: -

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 param。

所以我抓住了头脑,想想“啊”让我们尝试在selector / method参数中使用默认值false,并在计时器nil参数中传递userInfo。这样我就可以依赖每次调用的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)

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

1 个答案:

答案 0 :(得分:3)

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调用中的对象作为{ {1}}参数,然后您可以通过访问userInfostrobeTimerFired方法中访问该参数。