2015-07-28 13 views
9

Cercando di utilizzare dispatch_async in cui ho bisogno di una chiamata lanciabile, ma la nuova gestione degli errori di Swift e le chiamate al metodo mi confondono, se qualcuno mi può mostrare come farlo correttamente, o punto io nella giusta direzione, lo apprezzerei molto.dispatch_async() con throwables swift 2 Xcode 7

Codice:

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

Attenzione:

: la conversione non valida dal funzione del tipo di lancio '() genera -> _' per non gettare tipo di funzione '@convention (block)() -> Void '

risposta

11

FINA L EDIT: questo bug è stato risolto in Swift 2.0 final (Xcode 7 final).

Change

} catch let error as NSError { 

a

} catch { 

L'effetto è esattamente lo stesso - si può ancora print(error) - ma il codice verrà compilato e sarete sulla buona strada.

EDIT Ecco perché penso (come ho detto in un commento) che quello che hai trovato è un bug. Questo compila bene:

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

Il compilatore non si lamenta, e in particolare non ti costringe a scrivere func test() throws - dimostrando così che il compilatore pensa che questo catch è esaustivo.

Ma questo non può essere compilato:

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

Ma è la stessa identica do/catch blocchi! Quindi, perché non viene compilato qui? Penso che sia perché il compilatore è in qualche modo confuso dal blocco GCD circostante (da qui tutte le cose nel messaggio di errore relativo alla funzione @convention(block)).

Quindi, quello che sto dicendo è che entrambi dovrebbero compilare o entrambi non riuscirebbero a compilare. Il fatto che uno faccia e l'altro no è, penso, un bug nel compilatore, e ho presentato una segnalazione di bug proprio su questa base.

EDIT 2: Ecco un'altra coppia che illustra il bug (questo deriva dal commento di @ fqdn). Questo fa non di compilazione:

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

     } 
    } 
} 

Ma questo fa compilazione anche se è esattamente la stessa cosa:

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

     } 
    } 
    dispatch_async(dispatch_get_main_queue(), inner) 
} 

Tale incoerenza è il bug.

+0

Credo che quello che hai trovato sia un bug, anche se non ne sono del tutto sicuro. Per sicurezza, lo sto archiviando. – matt

+0

perfetto grazie! –

+1

@matt non è un bug, la cattura deve essere esaustiva per non chiudere la chiusura (che non è, 'lasciare che l'errore come NSError' sia disponibile) - vedere la mia risposta qui -> http: // stackoverflow. it/questions/31599615/how-to-throw-errors-in-a-closure-in-swift/31613855 # 31613855 – fqdn

Problemi correlati