Как вернуться из обработчика завершения внутри ленивого множества var - PullRequest
0 голосов
/ 30 декабря 2018

Я хочу получить api для получения контента с сервера внутри lazy var.Ниже приведен мой код, я не уверен, как заставить его работать.Любая подсказка?Я знаю, что мы не можем вернуться из обработчика завершения, поэтому я здесь потерян.Не уверены, какой еще способ добиться этого?

private(set) lazy var orderedViewControllers: [UIViewController] = {
        self.fetchPages()
    }()

func fetchPages() -> [UIViewController] {
    fetchIntroPages() { (result, error) in
        if error != nil {
        } else {
            if result?.data != nil { 
                if (result?.success)! {
                    var newColoredViewControllerArray: [UIViewController] = []
                    for page in result!.data! {
                        newColoredViewControllerArray.append(self.newColoredViewController(pageId: page.id!, pageTitle: page.title!, pageContent: page.content!))
                    }
                    // This will not work
                    return newColoredViewControllerArray
                }
            } else { 
            }
        }
    }
}

Ответы [ 2 ]

0 голосов
/ 30 декабря 2018

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

func fetchPages(_ completion: @escaping ([UIViewController]?) -> ()) {

    fetchIntroPages() { result, error in
        ...
            if let result = result { 
                if result.success {
                    ...
                    completion(newColoredViewControllerArray)
                    return
                }
            }
        }
        completion(nil)
    }

}

, затем не используйте переменную lazy, поскольку вы не можете обеспечить возвратзначение, так как вы делаете асинхронный вызов.Если вам это нужно, используйте просто «обычную» сохраненную переменную

var orderedViewControllers: [UIViewController]?

Теперь, где вам это нужно, позвоните fetchPages и в ее закрытии назначьте вашу переменную

fetchPages { viewControllers in
    if let viewControllers = viewControllers { // if you don't want to change controllers if there was any error
        self.orderedViewControllers = viewControllers
        ... // moment when you have `orderedViewControllers`
    }
}
0 голосов
/ 30 декабря 2018

Вы можете объявить глобальный массив [UIViewcontroller] и использовать семафор во время блока завершения

func fetchPages() -> [UIViewController] {
    var newColoredViewControllerArray = [UIViewController]()
    var semaphore = DispatchSemaphore(value: 0)
    fetchIntroPages() { (result, error) in
        if error != nil {
        } else {
            if result?.data != nil {
                if (result?.success)! {
                    for page in result!.data! {
                        newColoredViewControllerArray.append(self.newColoredViewController(pageId: page.id!, pageTitle: page.title!, pageContent: page.content!))
                    }
                }
            }
        }
        semaphore.signal()
    }
   semaphore.wait()
   return newColoredViewControllerArray
}

ИЛИ вы можете вернуть массив viewcontroller из использования завершения

func fetchPages(arrViewController:block) {
    var newColoredViewControllerArray = [UIViewController]()
    fetchIntroPages() { (result, error) in
        if error != nil {
        } else {
            if result?.data != nil {
                if (result?.success)! {
                    for page in result!.data! {
                        newColoredViewControllerArray.append(self.newColoredViewController(pageId: page.id!, pageTitle: page.title!, pageContent: page.content!))
                    }
                }
            }
        }
        arrViewController(newColoredViewControllerArray)

    }
}

Надеюсь, это полезнодля вас

...