do-catch 中的 Var init

Var init in do-catch

以下代码:

// Setup components
do {
    let captureDevice = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
    let deviceInput   = try AVCaptureDeviceInput(device: captureDevice)
    let output        = AVCaptureMetadataOutput()
    let session       = AVCaptureSession()
} catch {
    return false
}

此后您将无法访问已初始化的变量。如果我想访问例如错误是 "Use of unresolved identifier" deviceInput。但为什么? AVCaptureDeviceInput() 崩溃并且 catch-Block returns 或一切正确并且变量已成功初始化。解决此问题的最佳解决方案是什么?

do 块定义了一个新的范围。如果您在 do {} 内使用 letvar 声明变量,则它们只能在该块内访问。如果要在 do {} 之后使用它们,请在 do 语句之前声明它们。请注意,您不必给它们初始值,即使它们是用 let 声明的,因为您只需要在使用它们之前设置一次:

func foo() -> Bool {
    // Setup components
    let deviceInput: AVCaptureDeviceInput
    let captureDevice: AVCaptureDevice
    let output: AVCaptureMetadataOutput
    let session: AVCaptureSession

    do {
        captureDevice = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
        deviceInput   = try AVCaptureDeviceInput(device: captureDevice)
        output        = AVCaptureMetadataOutput()
        session       = AVCaptureSession()
    } catch {
        return false
    }

    // Do something to demo that the variables are accessible
    print(deviceInput.description)
    print(output.description)
    print(session.description)

    return false
}

Vacawama 的回答完全正确,但出于教育目的,这里有一个简化版本。除了 deviceInput 的初始化发生在 do 块内,你不需要任何东西:

func test() {
    let captureDevice = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
    let deviceInput : AVCaptureDeviceInput
    do { deviceInput = try AVCaptureDeviceInput(device: captureDevice) } catch {return}
    let output = AVCaptureMetadataOutput()
    let session  = AVCaptureSession()
    // ... other stuff here
    print("got to here")
}

如果 try 失败,"got to here" 永远不会打印;我们已经按部就班地退出了这个功能。

另一种方法可能是让你的周围函数抛出并直接执行它,根本没有 do...catch:

func test() throws {
    let captureDevice = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
    let deviceInput = try AVCaptureDeviceInput(device: captureDevice)
    let output = AVCaptureMetadataOutput()
    let session = AVCaptureSession()
    // ... other stuff here
    print("got to here")
}

这将错误检查的责任转移到 test() 的调用者身上。