do-catch中的var init

时间:2015-06-12 01:35:52

标签: 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
}

在此之后,您无法访问初始化变量。错误是"使用未解析的标识符"如果我想访问例如deviceInput。但为什么? AVCaptureDeviceInput()崩溃并且catch-Block返回或者all都正确并且变量已成功初始化。什么是解决这个问题的最佳解决方案?

2 个答案:

答案 0 :(得分:5)

do块定义了一个新范围。如果您在let内使用vardo {}声明变量,则只能在该块中访问它们。如果要在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
}

答案 1 :(得分:5)

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失败,"到达这里"从不打印;我们已经按顺序退出了这个职能。

还有一种方法可能是让你的周围函数抛出而只是去它,而根本没有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()的调用者身上。