Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/122.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios Swift-NSTimer为userInfo参数传递错误的值_Ios_Swift2_Nstimer - Fatal编程技术网

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

Ios Swift-NSTimer为userInfo参数传递错误的值,ios,swift2,nstimer,Ios,Swift2,Nstimer,我最近开始学习Swift编程语言,我喜欢它。为了帮助我学习,我一直在使用XCode 7开发几个简单的应用程序。其中一个应用是手电筒,一个功能是闪光灯。我决定使用NSTimer类来安排按设定的时间间隔调用flashlight toggle功能,从而提供一个很好的频闪效果。我第一次破解计时器代码如下:- NSTimer.scheduledTimerWithTimeInterval(0.5, target: self.torch, selector: "toggleTorch:", userInfo:

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

NSTimer.scheduledTimerWithTimeInterval(0.5, target: self.torch, selector: "toggleTorch:", userInfo: false, repeats: true)
正如您在这里看到的,我使用自己定制的Torch对象来处理flash切换功能。我将指定为实例变量的torch对象作为目标参数传递,然后在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
参数传递给计时器

因此,我搔搔头想“啊”,让我们尝试在选择器/方法参数中使用默认值
false
,并在计时器
userInfo
参数中传递
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大约三个星期了,因此我不是专家,因此计时器不会将
userInfo
信息作为参数传递给选择器。它将自身作为参数传递,以便您知道调用了哪个计时器

您应该按如下方式进行设置:

NSTimer.scheduledTimerWithTimeInterval(0.5, target: self.torch, selector: "strobeTimerFired:", userInfo: nil, repeats: true)
并在Torch对象中具有如下方法:

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


如果您确实需要使用
userInfo
进行某些操作(在本例中,您不需要),可以将原始
scheduledTimerWithTimeInterval
调用中的对象作为
userInfo
参数传递,然后您可以在
strobeTimerFired
方法中通过访问:
timer.userInfo

谢谢。我会尝试这一点,并标记为接受的答案,它的作品很好。这让我很困惑,因为user info参数是可选的AnyObject。如果在签名中实际指定为NSTimer,我可能会使用它。苹果课堂参考资料对我的喜好解释得并不充分,但我还在学习。我确信userInfo是可选的AnyObject有一个很好的理由。那不是NSTimer要去的地方。您可以将任何内容作为userInfo传入并在被调用的选择器中使用,而不是作为被调用选择器的参数。这总是NSTimer对象调用选择器。现在我明白了。谢谢你,戴夫。非常感谢。祝你新年快乐!如果你不介意的话,还有一个问题,戴夫,但这对我来说很烦人。我最初编写的选择器函数没有使用NSTimer作为参数,我应该这样做。当计时器调用选择器并发现不正确的参数类型时,为什么不在运行时爆炸并告诉我呢?第二,它是如何决定我所通过的那些谎言是真的。在Java中,我们有默认值。布尔isTrue;如果声明但未明确初始化,则为false。选择器需要一个NSTimer。很抱歉,我想在最后说…我可以理解选择器是否将任何对象作为参数。这是超类。。我们已经搞定了。但我已经明确指出这是一个布尔。