SWIFT - 如何解决回调发生得太晚
Posted
技术标签:
【中文标题】SWIFT - 如何解决回调发生得太晚【英文标题】:SWIFT - How to fix a callback occurring too late 【发布时间】:2019-02-14 04:09:59 【问题描述】:我正在进行网络调用,获取数据并希望通过向 tableVC 中的 var 提供数据来将该数据用于 tableVC。我遇到的问题是我的回调返回数据太晚了。下面是我的代码。非常感谢任何建议
来自网络管理员的代码
func getArticles(completion: @escaping PListCompletion)
guard let url = plistUrlString else return
let urlRequest = URLRequest(url: url)
let defaultConfig = URLSessionConfiguration.default
let session = URLSession(configuration: defaultConfig)
let task = session.dataTask(with: urlRequest) (data, response, error) in
do
if let data = data
let articles = try PropertyListDecoder().decode([Articles].self, from: data)
self.callBackOnMainThread(completion: completion, response: .success(response: PlistResponseData(results: articles)))
catch
print(error)
completion(.failure(error: error))
task.resume()
private func callBackOnMainThread(completion: @escaping PListCompletion, response: PlistResponse)
DispatchQueue.main.async
completion(response)
final class ArticleListProvider
var articles: [Articles]
convenience init()
self.init(articles: [])
self.provideArticles (article) in
self.articles.append(contentsOf: article)
init(articles: [Articles])
self.articles = articles
func articleCount() -> Int
//used for tableVC cells but returning 0
return self.articles.count
func articleAtIndex(_ index: Int) -> Articles?
return articles[index]
func provideArticles(completion: @escaping ([Articles]) -> Void)
ArticleDetailsNetworkManager.sharedInstance.getArticles [weak self] (response) in
guard let weakSelf = self else return
switch response
case .success(let plistData):
weakSelf.articles = plistData.results
case .failure(let error):
print(error.localizedDescription)
completion(weakSelf.articles)
表VC
final class ArticleListController: UITableViewController
fileprivate let CellIdentifier = "Cell"
fileprivate let articleListProvider: ArticleListProvider
override init(style: UITableViewStyle)
self.articleListProvider = ArticleListProvider()
super.init(style:style)
required init?(coder: NSCoder)
self.articleListProvider = ArticleListProvider()
super.init(coder: coder)
override func viewDidLoad()
super.viewDidLoad()
setupTableViewCell()
tableView.reloadData()
extension ArticleListController
func setupTableViewCell()
tableView.register(ArticleTableViewCell.self, forCellReuseIdentifier: CellIdentifier)
override func numberOfSections(in tableView: UITableView) -> Int
return 1
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
//this is returning 0 when it should be returning the amount of articles from the articleProvider, where the networking call is being made
return articleListProvider.articleCount()
我不知道这是否重要,但这适用于 Xcode 9.4,(尽管没有回调),升级到 10.1 后出现此问题
【问题讨论】:
【参考方案1】:这是一种期望的行为,api 调用是异步的,它不会立即返回任何内容。因此,在该 Web 服务返回结果之前,数组计数将为零。
改变你的初始化方法,如:
convenience init(callback: @escaping () -> Void)
self.init(articles: [])
self.provideArticles (article) in
self.articles.append(contentsOf: article)
callback()
并通过以下方式从您的视图控制器中使用它:
self.articleListProvider = ArticleListProvider [weak self]
guard let weakSelf = self else return
weakSelf.yourTableView.reloadData()
【讨论】:
这很有帮助 - 谢谢!我还必须将我的 articleListProvider 属性声明为可选属性才能使其正常工作。以上是关于SWIFT - 如何解决回调发生得太晚的主要内容,如果未能解决你的问题,请参考以下文章
Ajax请求回调地狱及解决方案(promiseasync和await)