**编辑:重新措辞,因为数组不是零,但它没有设置任何值,它应该**
这里是代码: var calendarArray:[Feed] = []
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
DispatchQueue.main.async {
self.calendarArray = self.dataFetcher.getRSSFeed(withURL: NSLocalizedString("CALENDAR", comment: ""), andIsAnEvent: false) as! [Feed]
}
let customNib = UINib(nibName: "UpcomingDatesCustomCell", bundle: nil)
datesTableView.register(customNib, forCellReuseIdentifier: "upcomingDatesCustomCell")
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = self.datesTableView.dequeueReusableCell(withIdentifier: "upcomingDatesCustomCell", for: indexPath) as! UpcomingDatesCustomCell
// update ui based off what's stored in calendarArray
return cell
}
这是在awakeFromNib中发生的。
在calendarArray
中访问cellForRowAtIndexPath
时,它超出范围......
这里发生了什么?
注意:我在主线程上运行异步,因为这是从在线提取的东西,我们有一个加载微调器。
答案 0 :(得分:2)
你不应该从numberOfRowsInSection
返回4。似乎在calendarArray
有任何项目之前调用此方法,因此您的界限出错。你为什么特意选择4?如果您尝试在calendarArray
中显示所有项目,请使用:
return calendarArray.count
此外,您可能不应该以这种方式使用数据填充数组。我在这里做出假设,但似乎您的dataFetcher.getRSSFeed
方法执行同步网络请求,因为您已将其包装在DispatchQueue.main.async
的调用中。这不会产生你想要的效果。通过这种方式调度,您可以有效地跳过一个运行循环,然后在主线程上运行代码。您应该调度到后台线程(而不是主线程)并在那里获取
或强>
您应该考虑使用NSURLSession
发出异步请求。出于多种原因,在iOS中同步获取数据并不是一个好主意。
编辑:其他信息
答案 1 :(得分:1)
您的代码:
DispatchQueue.main.async {
self.calendarArray = self.dataFetcher.getRSSFeed(withURL: NSLocalizedString("CALENDAR", comment: ""), andIsAnEvent: false) as! [Feed]
}
没有意义。你告诉编译器:“首先让我获得主线程,然后在后台线程中获取数据!”,这显然不会更新数组或UI。
这是您在进行多线程时应该做的事情:
DispatchQueue.global(attributes: [.qosDefault]).async {
// fetch data here
let contents = self.dataFetcher.getRSSFeed(withURL: NSLocalizedString("CALENDAR", comment: ""), andIsAnEvent: false)
DispatchQueue.main.async(execute: {
// UI Updates
self.calendarArray = contents
self.tableView.reloadData()
})
}
另外,正如@daltonclaybrook建议的那样,您还应该在calendarArray.count
numberOfRowsInSection
我建议您将其放在viewDidLoad
而不是awakeFromNib