1

次のコード:

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

この後、初期化された変数にアクセスできなくなります。たとえば、アクセスしたい場合、エラーは「未解決の識別子の使用」ですdeviceInput。しかし、なぜ?クラッシュして catch-Block が返されるかAVCaptureDeviceInput()、すべてが正しく変数が正常に初期化されます。これを解決するための最良の解決策は何ですか?

4

2 に答える 2

5

ブロックはdo新しいスコープを定義します。変数を 内または 内で宣言すると、letそのvarブロック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
}
于 2015-06-12T01:56:19.427 に答える
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()

于 2015-06-12T02:59:38.287 に答える