【问题标题】:dispatch_async() with throwables swift 2 Xcode 7dispatch_async() with throwables swift 2 Xcode 7
【发布时间】:2015-07-28 01:43:31
【问题描述】:

尝试使用 dispatch_async 我需要一个 throwable 调用,但是 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' 的无效转换

【问题讨论】:

    标签: xcode asynchronous error-handling swift2 xcode7-beta3


    【解决方案1】:

    最终编辑:此错误已在 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)
    }
    

    这种不一致就是错误。

    【讨论】:

    • 我相信你发现的是一个错误,虽然我不完全确定。以防万一,我正在归档它。
    • @matt 这不是一个错误,catch 需要详尽才能使闭包不会抛出(它不是,'let error as NSError' 是失败的) - 在这里查看我的答案 - > stackoverflow.com/questions/31599615/…
    • @fqdn 我不同意,因为如果你把他相同的 do/catch 结构放在一个普通函数中,比如func test() { do...catch...},它编译得很好。为什么?因为它详尽的!如果不是,您必须说func test() throws,而您不必这样做。
    • @fqdn 编辑了我的答案以提供实际示例来说明为什么我认为这是一个错误。
    • 伟大的更新!谢谢你的例子,这有助于说明这一点 - 为你的虫子提供更多食物! -> 如果您将第一个函数的名称 test 作为闭包参数传​​递给 dispatch_async(_:_:),编译器不会抱怨 :) 例如func test2() {dispatch_async(dispatch_get_main_queue(), test)} - 疯了...我有兴趣关注这个,有错误#?
    猜你喜欢
    • 1970-01-01
    • 2023-03-26
    • 2015-10-16
    • 2015-12-24
    • 1970-01-01
    • 2017-01-18
    • 2016-11-11
    • 2015-10-17
    • 2016-08-17
    相关资源
    最近更新 更多