dispatch_async() с помощью throwables swift 2 Xcode 7

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

Код:

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

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

: Неверное преобразование из бросающей функции типа '() throws -> _' в не бросающую функцию типа '@convention(block) () -> Void'


person justin shores    schedule 28.07.2015    source источник


Ответы (1)


ПОСЛЕДНИЕ РЕДАКТИРОВАНИЯ: эта ошибка исправлена ​​в Swift 2.0 final (Xcode 7 final).

Изменять

} catch let error as NSError {

to

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

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

person matt    schedule 28.07.2015
comment
Я считаю, что то, что вы нашли, является ошибкой, хотя я не совсем уверен. На всякий случай записываю. - person matt; 28.07.2015
comment
@matt это не ошибка, улов должен быть исчерпывающим, чтобы закрытие не сработало (что не так, «пусть ошибка как NSError» не работает) - см. мой ответ здесь -> stackoverflow.com/ вопросы/31599615/ - person fqdn; 28.07.2015
comment
@fqdn Я не согласен, потому что, если вы поместите ту же структуру do/catch в обычную функцию, скажем, func test() { do...catch...}, она отлично скомпилируется. Почему? Потому что он является исчерпывающим! Если бы это было не так, вы должны были бы сказать func test() throws, а не обязаны. - person matt; 28.07.2015
comment
@fqdn Отредактировал мой ответ, чтобы привести реальные примеры, показывающие, почему я считаю это ошибкой. - person matt; 28.07.2015
comment
отличное обновление! спасибо за пример, который помогает проиллюстрировать мысль - еще немного еды для вашего жука! -› если вы передадите имя своей первой функции test в качестве аргумента закрытия в dispatch_async(_:_:), компилятор не будет жаловаться :) например. func test2() {dispatch_async(dispatch_get_main_queue(), test)} - сумасшедший... Было бы интересно понаблюдать за этим, есть ошибка #? - person fqdn; 28.07.2015
comment
@fqdn Ооооо, хороший пример. Я украду его и добавлю в свой отчет об ошибке! Это номер радара 22023685, но я не думаю, что эта информация вам поможет; вы не можете заглянуть в базу ошибок Apple. Лучше всего подать отдельно. Чем больше, тем лучше! - person matt; 28.07.2015
comment
@fqdn Я добавил ваш пример в свой ответ. - person matt; 28.07.2015
comment
@matt: кажется, это улучшилось с Xcode 7 (окончательная версия). Все ваши примеры кода компилируются. catch is NSError предупреждает, что это всегда верно. catch let error as NSError теперь считается исчерпывающим (и Swift автоматически соединяет тип ErrorType и класс NSError). - person Martin R; 23.09.2015
comment
@MartinR Спасибо, я добавлю примечание к ответу, что теперь это исправлено. - person matt; 23.09.2015