异步后如何使全局数组不为空

Posted

技术标签:

【中文标题】异步后如何使全局数组不为空【英文标题】:How to make global array not empty after async 【发布时间】:2018-11-27 09:12:36 【问题描述】:

嘿,我无法访问我的全局数组,因为它是空的。我知道这个问题我已经在这个链接中问过How to access global array in Swift 4?

但他们没有在代码中显示它,所以我不明白如何实现它。谁能告诉我怎么做?这是我的代码

var prayers = [Prayer]() //This is my global array

func fetchPrayer() 
    guard let city = self.city else  return

    self.prayers = []
    APIServices.shared.fetchPrayer(name: city)  (results) in
        results.datetime.forEach( (time) in
            let shubuh = Prayer(prayerName: "Shubuh", prayerIcon: #imageLiteral(resourceName: "PartlyCloudyNight"), prayerTime: time.times.Fajr)
            let dzuhur = Prayer(prayerName: "Dzuhur", prayerIcon: #imageLiteral(resourceName: "Sunny"), prayerTime: time.times.Dhuhr)
            let ashar = Prayer(prayerName: "Ashar", prayerIcon: #imageLiteral(resourceName: "PartlyCloudyDay"), prayerTime: time.times.Asr)
            let maghrib = Prayer(prayerName: "Maghrib", prayerIcon: #imageLiteral(resourceName: "Overcast"), prayerTime: time.times.Maghrib)
            let isya = Prayer(prayerName: "Isya", prayerIcon: #imageLiteral(resourceName: "Clear"), prayerTime: time.times.Isha)
            self.prayers.append(contentsOf: [shubuh, dzuhur, ashar, maghrib, isya])

        )
        DispatchQueue.main.async 
            self.updateUI()
            self.tableView.reloadData()
        
    

这是我的表格视图代码,我把 func setupTableView 放在 viewDidLoad 中

extension PrayerController: UITableViewDelegate, UITableViewDataSource 
func setupTableView() 
    tableView.delegate = self
    tableView.dataSource = self
    tableView.register(PrayerTimeViewCell.self, forCellReuseIdentifier: self.cellId)
    tableView.separatorColor = .clear
    tableView.backgroundColor = .clear
    tableView.rowHeight = 53


//MARK:- TableView
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
    return prayers.count


func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
    let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! PrayerTimeViewCell

    let prayer = prayers[indexPath.row]
    cell.prayer = prayer

    return cell
  

这是代码的错误索引超出范围的地方

func updateUI() 
    let prayer0 = prayers[0].prayerTime
    let prayer1 = prayers[1].prayerTime
    let prayer2 = prayers[2].prayerTime
    let prayer3 = prayers[3].prayerTime
    let prayer4 = prayers[4].prayerTime

【问题讨论】:

您应该edit 您的问题以minimal reproducible example 的形式包含所有相关代码。 updateUI 是如何定义的?您的 tableView dataSource 方法设置正确吗?你也应该包括这些。 @DávidPásztor okey 我已经解决了我的问题,谢谢你提醒我:) 如何确定prayers 数组中有五个元素?请显示调用堆栈。 【参考方案1】:

首先,当呼叫updateUI 时,您如何确定prayers 数组中有五个祈祷?

其次,您应该避免可能的全局变量并发访问。我建议通过以下方式修改您的代码:

APIServices.shared.fetchPrayer(name: city)  (results) in
    var newPrayers = [Prayer]()
    results.datetime.forEach( (time) in
        let shubuh = Prayer(prayerName: "Shubuh", prayerIcon: #imageLiteral(resourceName: "PartlyCloudyNight"), prayerTime: time.times.Fajr)
        let dzuhur = Prayer(prayerName: "Dzuhur", prayerIcon: #imageLiteral(resourceName: "Sunny"), prayerTime: time.times.Dhuhr)
        let ashar = Prayer(prayerName: "Ashar", prayerIcon: #imageLiteral(resourceName: "PartlyCloudyDay"), prayerTime: time.times.Asr)
        let maghrib = Prayer(prayerName: "Maghrib", prayerIcon: #imageLiteral(resourceName: "Overcast"), prayerTime: time.times.Maghrib)
        let isya = Prayer(prayerName: "Isya", prayerIcon: #imageLiteral(resourceName: "Clear"), prayerTime: time.times.Isha)
        newPrayers.append(contentsOf: [shubuh, dzuhur, ashar, maghrib, isya])

    )
    DispatchQueue.main.async 
        self.prayers = newPrayers
        self.updateUI()
        self.tableView.reloadData()
    

在这里,您在 fetchPrayer 闭包中创建了一个本地 newPrayers 数组。您填充数组,完成后,在主线程中,然后通过将 self.prayers 分配给新数组来“发布”您的结果。

不过,在updateUI 中,您应该明确检查数组中的元素数量是否正确。

【讨论】:

嘿,你的第一个问题实际上我一直认为,当我在完成块中追加时,值将存储在我的全局数组中,但这就是问题所在,我不知道异步需要先完成。对于第二个问题,我需要在某个对象中获取一个值,这就是我需要使用并发的原因。还有其他方法可以获取某个对象中的值吗? 要从数组中取出一个元素,首先应该检查数组的count,以确保索引在有效范围内。

以上是关于异步后如何使全局数组不为空的主要内容,如果未能解决你的问题,请参考以下文章

java判断字符串是不是为空

如何判断Object对象不为空

如何使视图列不为空

如何在 Blazorise 上使验证日期不为空

如何重命名字段并使它们不为空

如何在 AWS REDSHIFT 中使现有列不为空?