异步后如何使全局数组不为空
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
,以确保索引在有效范围内。以上是关于异步后如何使全局数组不为空的主要内容,如果未能解决你的问题,请参考以下文章