等待直到异步调用完成,然后再运行"override".视图控制器的功能(快速) [英] Waiting until an asynchronous call is complete before running the "override" functions of a View Controller (Swift)

查看:42
本文介绍了等待直到异步调用完成,然后再运行"override".视图控制器的功能(快速)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在创建一个可从Alpha Vantage获取股票数据并显示它的应用程序,这是Swift的首次尝试(我通常使用JS开发).

I am creating an app that fetches stock data from Alpha Vantage and displays it, as a first attempt at Swift (I usually develop in JS).

更准确地说,我有一个表格视图,每个单元格都有以下标签:

More precisely, I have a table view, and each cell has the following labels:

  • 开放"价格标签
  • 高价"标签
  • 低"价格标签
  • 关闭"价格标签
  • 音量"标签

这是我用于单元格的自定义类.

This is the custom class I'm using for the cell.

    import UIKit

    class StockChoiceCell: UITableViewCell {

        @IBOutlet weak var openPriceLabel: UILabel!
        @IBOutlet weak var highPriceLabel: UILabel!
        @IBOutlet weak var lowPriceLabel: UILabel!
        @IBOutlet weak var closePriceLabel: UILabel!
        @IBOutlet weak var volumeLabel: UILabel!

    }

我有一个异步函数,该函数可以从Alpha Vantage成功检索所需的数据并返回 [DataPoint] ,其中DataPoint是包含开盘价,最高价,最低价和收盘价的结构.音量.我说成功了,因为我在应用程序的另一个方面使用了该功能,而没有任何问题.

I have an asynchronous function that successfully retrieves the desired data from Alpha Vantage and returns [DataPoint], where DataPoint is a struct that contains the open, high, low and close prices, as well as the volume. I say successful, as I use the function in another facet of the app without issues.

该功能类似于:

func retrieveDataFromAPI (tic: String, completion: @escaping ([DataPoint])->()) {

// Fetch stuff

// Pack it under the DataPoint structure

// ...

completion(arrayOfDataPoints)

}

这是问题所在.

由于该函数的异步特性,我不知道如何使应用程序在运行之前等待"完成数据提取:

Here is the issue.

Due to the asynchronous nature of the function, I do not know how to make the application "wait" for the data fetching to complete before running:

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
    {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! StockChoiceCell

        // ... Setting stuff, etc.

        return cell
    } 

我在线搜索,主要尝试以下两篇文章,因为我的尝试之一是将异步函数嵌套在另一个同步函数中

I searched online, trying primarily the following two posts, as one of my attempts consisted of nesting the asynchronous function within another synchronous function:

如果这是JS,我将立即使用Promise.但是Swift对我来说是新手,我仍在探索异步函数如何在该语言中工作.

If this were JS, I'd immediately use a Promise. But Swift is new to me, and I am still exploring how asynchronous functions work in the language.

谢谢!

推荐答案

由于该函数的异步特性,在运行 cellForRowAtIndexPath

好吧,当没有数据提供给表视图时, cellForRowAtIndexPath 将自动不执行".请记住,这是一个表视图数据源方法.您不能直接调用它.因此,只需像通常那样实现 cellForRowAtIndexPath 即可.如果 numberOfRowsInSection 返回0,那么将不会调用 cellForRowAtIndexPath ,会吗?

Well, cellForRowAtIndexPath will automatically "not execute", when there are no data supplied to the table view. Remember that this is a table view data source method. You don't get to call it directly. So just implement cellForRowAtIndexPath as you would normally. If numberOfRowsInSection returns 0, then cellForRowAtIndexPath would not be called, would it?

我想您已经用这样的一行实现了 numberOfRowsInSection :

I would imagine you have implemented numberOfRowsInSection with a line like this:

return dataSource.count

其中 dataSource 是VC的属性,类型为 [DataPoint] .最初,将此 dataSource 属性设置为一个空数组:

where dataSource is a property of your VC, of type [DataPoint]. Initially, set this dataSource property to an empty array:

var dataSource = [DataPoint]()

并且在加载表视图时,它不会显示任何内容,因为尚未获取数据.现在在 viewDidLoad 中,我们调用此异步函数来获取数据:

And when the table view loads, it will display nothing, because the data has not been fetched. Now in viewDidLoad, we call this async function to fetch the data:

retrieveDataFromAPI(tic: "some string") {
    dataFetched in
    DispatchQueue.main.async {
        self.dataSource = dataFetched
        self.tableView.reloadData() // this calls the table view data source methods again
    }
}

当您调用 reloadData 时, dataSource 将不再为空,并且将为相应的索引路径调用 cellForRowAtIndexPath .

At the time you call reloadData, dataSource will no longer be empty, and cellForRowAtIndexPath will be called for the appropriate index paths.

请注意,Swift有 PromiseKit ,您可能熟悉也可能不熟悉.

Note that there is PromiseKit for Swift, which you may or may not find familiar.

这篇关于等待直到异步调用完成,然后再运行"override".视图控制器的功能(快速)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆