9

尝试使用 dispatch_async 我需要一个可抛出的调用,但是 Swift 的新错误处理和方法调用让我感到困惑,如果有人能告诉我如何正确地做到这一点,或者指出我正确的方向,我将不胜感激。

代码:

func focusAndExposeAtPoint(point: CGPoint) {
    dispatch_async(sessionQueue) {
        var device: AVCaptureDevice = self.videoDeviceInput.device

        do {

            try device.lockForConfiguration()
            if device.focusPointOfInterestSupported && device.isFocusModeSupported(AVCaptureFocusMode.AutoFocus) {
                device.focusPointOfInterest = point
                device.focusMode = AVCaptureFocusMode.AutoFocus
            }

            if device.exposurePointOfInterestSupported && device.isExposureModeSupported(AVCaptureExposureMode.AutoExpose) {
                device.exposurePointOfInterest = point
                device.exposureMode = AVCaptureExposureMode.AutoExpose
            }

            device.unlockForConfiguration()
        } catch let error as NSError {
            print(error)
        }
    }
}

警告:

: 从 '() throws -> _' 类型的抛出函数到非抛出函数类型 '@convention(block) () -> Void' 的无效转换

4

1 回答 1

11

最终编辑:此错误已在 Swift 2.0 final(Xcode 7 final)中修复。

改变

} catch let error as NSError {

} catch {

效果是完全一样的——你仍然可以print(error)——但是代码会编译,你会继续前进。

编辑这就是为什么我认为(正如我在评论中所说)你发现的是一个错误。这编译得很好:

func test() {
    do {
        throw NSError(domain: "howdy", code: 1, userInfo:nil)
    } catch let error as NSError {
        print(error)
    }
}

编译器不会抱怨,特别是不会强迫你写func test() throws——因此证明编译器认为这catch是详尽无遗的。

但这不会编译:

func test() {
    dispatch_async(dispatch_get_main_queue()) {
        do {
            throw NSError(domain: "howdy", code: 1, userInfo:nil)
        } catch let error as NSError {
            print(error)
        }
    }
}

但它是完全相同的do/catch块!那么为什么不在这里编译呢?我认为这是因为编译器在某种程度上被周围的 GCD 块弄糊涂了(因此错误消息中关于@convention(block)函数的所有内容)。

所以,我要说的是,要么他们都应该编译,要么他们都应该编译失败。我认为一个有而另一个没有的事实是编译器中的一个错误,我正是基于此提交了一份错误报告。

编辑 2:这是另一个说明错误的对(来自@fqdn 的评论)。这不会编译

func test() {
    dispatch_async(dispatch_get_main_queue()) {
        do {
            throw NSError(domain: "howdy", code: 1, userInfo:nil)
        } catch is NSError {

        }
    }
}

但这确实可以编译,即使它完全相同:

func test() {
    func inner() {
        do {
            throw NSError(domain: "howdy", code: 1, userInfo:nil)
        } catch is NSError {

        }
    }
    dispatch_async(dispatch_get_main_queue(), inner)
}

这种不一致就是错误。

于 2015-07-28T01:50:20.197 回答