Возврат значения из блока завершения / закрытия, используемого в методе источника данных - PullRequest
0 голосов
/ 26 октября 2018

У меня есть пользовательское представление, которое будет отображаться в представлении коллекции. Представление будет добавлено в виде стека, встроенного в контроллер представления. Метод источника данных предоставляется для предоставления объекта представления.

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

Вот демонстрационный код только для лучшего понимания. Прости меня за мои ужасные соглашения об именах.

func customeViewInStack(customView: UIView) -> [UIView]? {

        if viewIsAllowedToBeDisplayed {
            self.downloadViewContent(onCompletionHandler: { contentDownloadSuccessfull in
                if contentDownloadSuccessfull
                // Return new instance of my custom view
                else
                // return nil
            })
        }

        return nil
    }

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

Редактировать 1

Я обновил фрагмент кода для лучшего понимания. Я не могу изменить сигнатуру функции, поскольку она является частью фреймворка и метода источника данных.

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

Может кто-нибудь подсказать мне, как мне решить эту проблему

Спасибо

Ответы [ 2 ]

0 голосов
/ 26 октября 2018

Вам нужно будет объявить свой собственный блок завершения и использовать его, чтобы получить новый вид:

Вот как выглядит это объявление:

// Declaration
func customeViewInStack(customView: UIView, completion: @escaping ([UIView]? -> ()) {
    self.checkIfViewShouldBeShown(onCompletionHandler: { shouldDisplayView in
        if shouldDisplayView
            // Call the completion block with the views
            completion(views)
        else
            // Call the completion block with nil
            completion(nil)
    })
}

И затем при использовании этого вы будете использовать его так же, как вы использовали метод checkIfViewShouldBeShown:

customViewInStack(customView: customView, completion: { views in
    guard let views = views else {
        // Views are nil
    }

    // Do what you need to do with views
})
0 голосов
/ 26 октября 2018

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

func customeViewInStack(customView: UIView, completion: @escaping ([UIView]?) -> Void) {

    self.checkIfViewShouldBeShown(onCompletionHandler: { shouldDisplayView in
        completion(shouldDisplayView ? [...(put the stack of views to return here))] : nil)
    })
}

РЕДАКТИРОВАТЬ: я плохо читал в первый раз, поэтому я улучшил свой ответ.

Поскольку вам нужно передать его в представление коллекции, я предлагаю вам впоследствии сохранить его и перезагрузить коллекцию:

private var viewsForCollection: [UIView] = []

customeViewInStack(customView: UIView(), completion: { [weak self] views in
   self?.viewsForCollection = views ?? [] // I guess optionality for array is unnecessary
   self?.collectionView.reloadData()
})

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

...