Функция закрытия @escaping в Swift 3

Ошибка с этой функцией ниже Closure use of non-escaping parameter 'completion' may allow it to escape

func retrieveCannedRecommendedEntities() -> Future<CannedRecommendedEntities, NSError> {
  return Future() { completion in
    self.retrieve(.onboarding) { response in
      switch response {
      case .success(let val):
        let payload: AnyObject = val.value.json! as AnyObject
        let json = JSON(payload)

        guard let suggestions = self.parseEntitiesFromJSON(json, atKey: "suggestion") else {
          completion(SqorResult.error(self.parsingError))
        }

        let teams = suggestions.filter {
          $0.entityType != .Player
        }

        let athletes = suggestions.filter {
          $0.entityType == .Player
        }

        completion(SqorResult.success(Box((teams, athletes))))

      case .error(let error):
        completion(SqorResult.error(error))
      }
    }
  }
}

2 ответа

Говорят, что замыкание экранирует функцию, когда замыкание передается в качестве аргумента функции, но вызывается после ее возврата.

Если вы используете асинхронность замыкания, то есть замыкание может быть вызвано после выполнения функции, вам нужно добавить @escaping,

Даже если у вас нет ошибок компиляции, вы можете иметь ошибку времени выполнения, потому что память закрытия может быть освобождена.

@escapingуверяю вас, чтобы предотвратить ваше закрытие.

Ошибка компилятора означает, что параметр completion в функции Future- который является закрытием - указывается как "не выходящий" (это по умолчанию). Это значит, что закрытие completion должен быть выполнен перед функцией Future возвращается.

Однако реализация указывает на то, что completion может "избежать" функции Future - Который означает, что completion может быть выполнен после функции Future возвращается.

Для того, чтобы исправить эту ошибку программиста, вы должны убедиться, что закрытие completion будет выполнен перед функцией Future возвращает, или вам нужно добавить модификатор @escaping к параметру completion,

Смотрите также Escape E-Closures

Обратите внимание, что оба решения могут иметь последствия, потому что они либо требуют изменения API функции, возможно определенной в существующей библиотеке (например, "Future"), либо это несовместимо с вашим вариантом использования, так как вы вызываете completion в другом - возможно, экранирующем - закрытии, которое устанавливается в качестве параметра в self.retrieve,

Тем не менее, понятие "завершение" в контексте "будущего" четко диктует, что completion должен быть "убегающим". Итак, добавляя @escaping к функции подписи Future Кажется, чтобы идти.

Другие вопросы по тегам