Trying to use dispatch_async in which i need a throwable call, but Swift's new error handling, and method calls are confusing me, if anyone could show me how to do this correctly, or point me in the right direction, I would greatly appreciate it.
Code:
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)
}
}
}
Warning:
: Invalid conversion from throwing function of type '() throws -> _' to non-throwing function type '@convention(block) () -> Void'
FINAL EDIT: This bug is fixed in Swift 2.0 final (Xcode 7 final).
Change
} catch let error as NSError {
to
} catch {
The effect is exactly the same — you can still print(error)
— but the code will compile and you'll be on your way.
EDIT Here's why I think (as I said in a comment) that what you've found is a bug. This compiles just fine:
func test() {
do {
throw NSError(domain: "howdy", code: 1, userInfo:nil)
} catch let error as NSError {
print(error)
}
}
The compiler does not complain, and in particular does not force you to write func test() throws
— thus proving that the compiler thinks this catch
is exhaustive.
But this does not compile:
func test() {
dispatch_async(dispatch_get_main_queue()) {
do {
throw NSError(domain: "howdy", code: 1, userInfo:nil)
} catch let error as NSError {
print(error)
}
}
}
But it's the exact same do/catch
blocks! So why doesn't it compile here? I think it's because the compiler is somehow confused by the surrounding GCD block (hence all the stuff in the error message about the @convention(block)
function).
So, what I'm saying is, either they should both compile or they should both fail to compile. The fact that one does and the other doesn't is, I think, a bug in the compiler, and I have submitted a bug report on precisely that basis.
EDIT 2: Here's another pair that illustrates the bug (this comes from @fqdn's comment). This does not compile:
func test() {
dispatch_async(dispatch_get_main_queue()) {
do {
throw NSError(domain: "howdy", code: 1, userInfo:nil)
} catch is NSError {
}
}
}
But this does compile even though it is exactly the same thing:
func test() {
func inner() {
do {
throw NSError(domain: "howdy", code: 1, userInfo:nil)
} catch is NSError {
}
}
dispatch_async(dispatch_get_main_queue(), inner)
}
That inconsistency is the bug.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With