无法让 API 调用及时运行 tableview swift 4 xcode 9

Posted

技术标签:

【中文标题】无法让 API 调用及时运行 tableview swift 4 xcode 9【英文标题】:Cannot get API call to run in time for tableview swift 4 xcode 9 【发布时间】:2018-04-28 02:40:59 【问题描述】:

我正在尝试获取 API 调用来填充列表视图的单元格,但似乎无法在生成单元格之前获取要收集的数据。我曾尝试制作像here 这样的完成处理程序,但无济于事以及来自同一链接的信号量。在完成处理程序编译时,它在执行时仍然没有及时获取数据(诚然,这是我第一次尝试完成处理程序)。这是没有完成处理程序的原始代码:

override func viewDidLoad() 
    super.viewDidLoad()

    RestaurantListView.delegate = self
    RestaurantListView.dataSource = self
    //API setup
    guard let url = URL(string: "https://myURL.com") else 
        print("ERROR: Invalid URL")
        return
    
    let task = URLSession.shared.dataTask(with: url) 

        (data, response, error) -> Void in

        // URL request is complete
        guard let data = data else 
            print("ERROR: Unable to access content")
            return
        

        guard let blog = try? JSONDecoder().decode(Blog.self, from: data) else 
            print("Error: Couldn't decode data into Blog")
            return
        
        self.myData = blog
    
    task.resume()

表格和单元格在这些函数下面初始化:

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
    return 100


func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
    let cell = RestaurantListView.dequeueReusableCell(withIdentifier: "cell")
    cell?.textLabel?.text = myAPIValue
    return cell!
    

我有几个打印语句来跟踪程序,它通过 viewDidLoad 然后第一个 tableView 设置表格然后第二个处理单元格,最后它通过 URL 任务。

我已经重写了几十种不同的方式,但不知道如何使它以正确的顺序执行。

【问题讨论】:

【参考方案1】:

您需要重新加载表格,因为这一行 URLSession.shared.dataTask(with: url) 触发了一个与您的代码行顺序不同的异步任务

guard let blog = try? JSONDecoder().decode(Blog.self, from: data) else 
     print("Error: Couldn't decode data into Blog")
     return

self.myData = blog

DispatchQueue.main.async
    RestaurantListView.reloadData()

【讨论】:

【参考方案2】:

您必须将数据保存在变量中,如下所示,我使用了 arrayOfData。查看保存数据后调用的reloadData()函数。

func downloadData ()
    let url = URL(string: "http://www.url.com")

    if let url = url 
        let task = URLSession.shared.dataTask(with: url, completionHandler: (data, response, error) in
            do 
                if let dataResponse = data
                    let responseDecoded = try JSONDecoder().decode(Response.self, from: dataResponse)
                    DispatchQueue.main.async 
                        self.arrayOfData = responseDecoded.results ?? []
                        self.RestaurantListView.reloadData()
                    
                 
            
            catch 
                print("Error: \(error)")
            
        )

        task.resume()
    

您必须使协议与该数据保持一致

func numberOfSections(in tableView: UITableView) -> Int 
    return 1


func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
    /**If you have no elements you should return 0**/
    return arrayOfData.count


func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
    if let cell = RestaurantListView.dequeueReusableCell(withIdentifier: "cell")
        cell.textLabel?.text = arrayOfData[indexPath.row].name
        return cell
    
    return UITableViewCell()

【讨论】:

以上是关于无法让 API 调用及时运行 tableview swift 4 xcode 9的主要内容,如果未能解决你的问题,请参考以下文章

像刷新一样重新加载tableview视图

REST API:无法填充 Tableview

如何让 tableView.reloadData() 与核心数据正常工作?

你写的什么垃圾代码让Vsync命令不能及时处理呢?

尝试调用 tableView.reloadData 时出现 NSInvalidArgumentException?

调用需要 API 级别 21(让 camera2 在低于 21 的设备上运行?)[重复]