2015-07-28 9 views
9

Der Versuch, dispatch_async zu verwenden, in dem ich einen anwählbaren Anruf benötige, aber Swifts neue Fehlerbehandlung und Methodenaufrufe verwirren mich, wenn mir jemand zeigen könnte, wie man das richtig macht oder zeigt Ich in die richtige Richtung, ich würde es sehr schätzen.dispatch_async() mit throwables swift 2 Xcode 7

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) 
     } 
    } 
} 

Warnung:

: Ungültige Konvertierung von Funktion vom Typ werfen '() wirft -> _' zu nicht-Wurf Funktionstyp ‚@convention (Block)() -> Void '

Antwort

11

FINA L EDIT: Dieser Fehler wurde in Swift 2.0 final (Xcode 7 final) behoben.

ändern

} catch let error as NSError { 

zu

} catch { 

Die Wirkung ist genau das gleiche - Sie noch print(error) können - aber der Code kompiliert und Sie werden auf Ihrem Weg.

EDIT Hier ist, warum ich denke (wie ich in einem Kommentar sagte), dass was Sie gefunden haben, ist ein Bug. Dies kompiliert just fine:

func test() { 
    do { 
     throw NSError(domain: "howdy", code: 1, userInfo:nil) 
    } catch let error as NSError { 
     print(error) 
    } 
} 

Der Compiler beschwert sich nicht, insbesondere nicht zwingen Sie nicht func test() throws zu schreiben - was beweist, dass der Compiler denkt, dass dieses catch erschöpfend ist.

Aber das lässt sich nicht kompilieren:

func test() { 
    dispatch_async(dispatch_get_main_queue()) { 
     do { 
      throw NSError(domain: "howdy", code: 1, userInfo:nil) 
     } catch let error as NSError { 
      print(error) 
     } 
    } 
} 

Aber es ist genau die gleichen do/catch Blöcke! Also warum kompiliert es hier nicht? Ich denke, es liegt daran, dass der Compiler durch den umgebenden GCD-Block irgendwie verwirrt ist (daher alle Dinge in der Fehlermeldung über die @convention(block)-Funktion).

Also, was ich sage ist, entweder sollten sie beide kompilieren oder beide sollten nicht kompilieren. Die Tatsache, dass der eine das tut, und der andere nicht, ist meiner Meinung nach ein Fehler im Compiler, und genau auf dieser Grundlage habe ich einen Fehlerbericht eingereicht.

BEARBEITEN 2: Hier ist ein weiteres Paar, das den Fehler veranschaulicht (das kommt von @ fqdn Kommentar). Dies gilt nicht Kompilierung:

func test() { 
    dispatch_async(dispatch_get_main_queue()) { 
     do { 
      throw NSError(domain: "howdy", code: 1, userInfo:nil) 
     } catch is NSError { 

     } 
    } 
} 

Aber das tut Kompilierung, obwohl es genau das Gleiche ist:

func test() { 
    func inner() { 
     do { 
      throw NSError(domain: "howdy", code: 1, userInfo:nil) 
     } catch is NSError { 

     } 
    } 
    dispatch_async(dispatch_get_main_queue(), inner) 
} 

Diese Inkonsistenz der Fehler ist.

+0

Ich glaube, was Sie gefunden haben, ist ein Fehler, obwohl ich mir nicht ganz sicher bin. Nur für den Fall, ich füge es ein. – matt

+0

perfekt danke! –

+1

@matt es ist kein Fehler, der Fang muss erschöpfend sein, damit die Schließung nicht werfen (was es nicht ist, "lass Fehler als NSError" ist nicht möglich) - siehe meine Antwort hier -> http: // stackoverflow. com/questions/31599615/how-to-throw-Fehler-in-ein-Schließung-in-swift/31613855 # 31613855 – fqdn