Свифт: Как я могу вызвать свою функцию внутри тела завершения? - PullRequest
0 голосов
/ 14 января 2020

У меня есть предопределенная функция с параметром завершения:

func checkNotificationEnabled(_ resultBlock : ((Bool)->())? = nil){
    Bool enabled = false

    ... a big block of code that gets enabled value 
    ...
    ... end block

    resultBlock?(enabled)
}

Мне нужно получить значение true / false и передать его другой функции:

@objc
func isNotificationEnabled(_
    resolve: RCTPromiseResolveBlock, rejecter reject: RCTPromiseRejectBlock
) -> Void {
    checkNotificationEnabled { (enabled:Bool) in
        resolve(enabled)
    }
}

Получена ошибка : Выходное закрытие захватывает неэкранирующий параметр 'resol'

Как мне передать enabled в resolve?

Ответы [ 2 ]

0 голосов
/ 14 января 2020
  • resolve аргумент передается в функцию checkNotificationEnabled, но не помечается @ escaping
  • (Bool)->())? = nil необязательно: по умолчанию nil, поэтому нет необходимости назначать nil
  • (Bool)->() это равно более читаемой версии Void.

typealias ResultBlock = (Bool) -> Void
func checkNotificationEnabled(_ resultBlock: ResultBlock?) {
    var enabled = false

    ... a big block of code that gets enabled value 
    ...
    ... end block

    resultBlock?(enabled)
}

@objc
func isNotificationEnabled(_
    resolve: @escaping RCTPromiseResolveBlock, rejecter reject: RCTPromiseRejectBlock) {
    checkNotificationEnabled { enabled in
        resolve(enabled)
    }
}

Выход из замыканий

Говорят, что замыкание экранирует функцию, когда замыкание передается в качестве аргумента для функция, но вызывается после возврата функции. Когда вы объявляете функцию, которая принимает замыкание в качестве одного из своих параметров, вы можете написать @escaping перед типом параметра, чтобы указать, что закрытию разрешено экранировать.

Один из способов, которым закрытие может быть экранировано, - хранится в переменной, определенной за пределами функции. Например, многие функции, которые запускают асинхронную операцию, принимают аргумент замыкания в качестве обработчика завершения. Функция возвращается после запуска операции, но замыкание не вызывается до тех пор, пока операция не будет завершена - замыкание необходимо закрыть, чтобы вызвать его позже. источник

0 голосов
/ 14 января 2020

Если предположить, что RCTPromiseResolveBlock на func isNotificationEnabled является неким блоком, который вы пытаетесь выполнить в отношении completion из func checkNotificationEnabled, завершение фактически «ускользает» (переживает) область действия функции, и компилятор просто жалуется на то, что ваш RCTPromiseResolveBlock может не быть живым (во время выполнения) во время обратного вызова завершения

Вам нужно будет пометить @escaping параметром 'resolve', чтобы обойти это.

Вы определенно получите больше ясности, когда поймете, что такое экранирование. Посмотрите на этот вопрос: Спасение замыканий в Swift

Надеюсь, это поможет.

...