2015-07-28 2 views
9

Пытается использовать dispatch_async, в котором мне нужен разворачиваемый вызов, но новая обработка ошибок Swift и вызовы методов меня путают, если кто-нибудь может показать мне, как это сделать правильно, или указать я в правильном направлении, я был бы очень признателен.dispatch_async() с throwables swift 2 Xcode 7

Код:

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

Предупреждение:

: Invalid преобразования метания функции типа '() броски -> _', чтобы не-бросание типа функции «@convention (блок)() -> Void '

ответ

11

FINA L EDIT: эта ошибка исправлена ​​в финале Swift 2.0 (окончание Xcode 7).

Изменить

} catch let error as NSError { 

в

} catch { 

Эффект точно такой же - вы все равно можете print(error) - но код будет компилироваться, и вы будете на вашем пути.

EDIT Вот почему я думаю (как я уже сказал в комментарии), что вы обнаружили ошибку. Это компилируется нормально:

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

Компилятор не жалуется, и, в частности, не заставит вас писать func test() throws - тем самым доказав, что компилятор считает, что это catch является исчерпывающим.

Но это не компилируется:

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

Но это те же самые do/catch блоки! Так почему же он не компилируется здесь? Я думаю, что это связано с тем, что компилятор каким-то образом смущен окружающим блоком GCD (отсюда и все, что содержится в сообщении об ошибке в функции @convention(block)).

Итак, я говорю, либо они должны скомпилировать, либо оба они не скомпилируются. То, что один делает, а другой - нет, я думаю, ошибка в компиляторе, и я представил отчет об ошибке именно на этой основе.

EDIT 2: Вот еще одна пара, которая иллюстрирует ошибку (это происходит из комментария @ fqdn). Это делает не компиляции:

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

     } 
    } 
} 

Но это делает компиляции, хотя это одно и то же:

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

     } 
    } 
    dispatch_async(dispatch_get_main_queue(), inner) 
} 

Это несоответствие является ошибкой.

+0

Я верю, что вы нашли ошибку, хотя я не совсем уверен. На всякий случай, я подаю его. – matt

+0

безупречное спасибо! –

+1

@matt это не ошибка, уловка должна быть исчерпывающей, чтобы закрытие не бросалось (чего нет, «пусть ошибка как NSError» не поддается) - см. Мой ответ здесь -> http: // stackoverflow. com/questions/31599615/how-to-throw-errors-in-a-clos-in-swift/31613855 # 31613855 – fqdn

Смежные вопросы