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)

当后台只接受字符串得时候,在传输复杂得数据得时候会发生得问题

如何使 CreateFile 尽可能快

借鉴Alamofire解决异步回调问题(Swift)

多个回调而不是在swift中使用Delegates

如何解决此回调包含问题?