do-catch中的var init

fla*_*pys 1 swift swift2

以下代码:

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

在此之后,您无法访问初始化变量.如果我想访问例如,则错误是"使用未解析的标识符" deviceInput.但为什么?要么AVCaptureDeviceInput()崩溃与追赶块返回或全部是正确和变量初始化成功.什么是解决这个问题的最佳解决方案?

vac*_*ama 5

do块定义了一个新范围.如果您使用letvar在其中声明变量do {},那么它们只能在该块中访问.如果你想在之后使用它们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
}
Run Code Online (Sandbox Code Playgroud)


mat*_*att 5

Vacawama的答案完全正确,但仅出于教育目的,这里是简化版.除了deviceInputdo块内发生的初始化之外,您不需要任何其他内容:

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")
}
Run Code Online (Sandbox Code Playgroud)

如果try失败,"到这里"永远不会打印; 我们已经退出了良好的秩序.

还有一种方法可能是让你的周围函数抛出而只是去它,完全没有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")
}
Run Code Online (Sandbox Code Playgroud)

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