fatal error: Index out of range when refreshing table view
fatal error: Index out of range when refreshing table view
拉动刷新时我遇到了这个奇怪的应用程序崩溃问题。
我的代码如下:
var posts: [Posts] = []
override func viewDidLoad() {
super.viewDidLoad()
// refreshControl -> pull to refresh handler
let refreshControl = UIRefreshControl()
refreshControl.addTarget(self,
action: #selector(Main_TVC.getData),
for: UIControlEvents.valueChanged)
self.refreshControl = refreshControl
getData()
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return posts.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell",
for: indexPath) as! PostsTableViewCell
cell.titleLabel.text = posts[indexPath.row].postTitle
cell.bodyLabel.text = posts[indexPath.row].postBody
return cell
}
func getData() {
self.posts.removeAll()
// queries the backend and fills the data - sorry for code omission
refresh()
}
func refresh() {
self.tableView.reloadData()
self.refreshControl?.endRefreshing()
}
应用程序运行正常,即使我下拉刷新,一切都运行完美,但是如果长时间下拉刷新,就像下拉几乎触及屏幕底部,应用程序崩溃并提示以下内容错误:
致命错误:索引超出范围
上线
cell.titleLabel.text = posts[indexPath.row].post标题
如果我打印 post 计数和 indexPath 如下:
打印("posts.count = (posts.count)")
打印("indexPath.row = (indexPath.row)")
我正常下拉的时候打印的是正确的数据,但是如果像长拉一样往下拉,崩溃时如果提示是全屏的
posts.count = 0
indexPath.row = 2
我在这里使用 refreshControl 时从未发生过这种事情。
希望我的信息能被理解,主要是关于长拉刷新问题。
您的问题是您在 getData
中做的第一件事是删除 self.posts
中的所有帖子,但您没有(大概是因为缺少代码)重新加载 table 视图,所以现在数组中的帖子数 (0) 和 tableview * 认为在数组中的帖子数(不是零)不同,所以你会遇到数组边界崩溃。
在 self.posts.removeAll()
之后调用 reloadData
会解决问题,但会导致 table 视图 'flashing',因为它重新绘制为空,然后使用新数据重新绘制。
由于您没有显示 getData
的完整代码,我无法提供您需要的确切代码,但它应该类似于:
func getData() {
fetchPostsWithCompletion() {
if let tempPosts = dataFromNetwork {
self.posts = tempPosts
} else {
self.posts.removeAll()
}
self.refresh() // Dispatch this on the main queue if your completion handler is not already on the main queue
}
}
这样您就可以在获得新数据之前不操作支持数组。
我刚遇到同样的问题。我的发现是在 posts
数组上延迟 removeAll()
的执行允许 table 视图在其 count
.
上更新
func getData() {
self.delayExecutionByMilliseconds(500) {
self.posts.removeAll()
}
// queries the backend and fills the data - sorry for code omission
refresh()
}
fileprivate func delayExecutionByMilliseconds(_ delay: Int, for anonFunc: @escaping () -> Void) {
let when = DispatchTime.now() + .milliseconds(delay)
DispatchQueue.main.asyncAfter(deadline: when, execute: anonFunc)
}
拉动刷新时我遇到了这个奇怪的应用程序崩溃问题。
我的代码如下:
var posts: [Posts] = []
override func viewDidLoad() {
super.viewDidLoad()
// refreshControl -> pull to refresh handler
let refreshControl = UIRefreshControl()
refreshControl.addTarget(self,
action: #selector(Main_TVC.getData),
for: UIControlEvents.valueChanged)
self.refreshControl = refreshControl
getData()
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return posts.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell",
for: indexPath) as! PostsTableViewCell
cell.titleLabel.text = posts[indexPath.row].postTitle
cell.bodyLabel.text = posts[indexPath.row].postBody
return cell
}
func getData() {
self.posts.removeAll()
// queries the backend and fills the data - sorry for code omission
refresh()
}
func refresh() {
self.tableView.reloadData()
self.refreshControl?.endRefreshing()
}
应用程序运行正常,即使我下拉刷新,一切都运行完美,但是如果长时间下拉刷新,就像下拉几乎触及屏幕底部,应用程序崩溃并提示以下内容错误:
致命错误:索引超出范围
上线
cell.titleLabel.text = posts[indexPath.row].post标题
如果我打印 post 计数和 indexPath 如下:
打印("posts.count = (posts.count)") 打印("indexPath.row = (indexPath.row)")
我正常下拉的时候打印的是正确的数据,但是如果像长拉一样往下拉,崩溃时如果提示是全屏的
posts.count = 0
indexPath.row = 2
我在这里使用 refreshControl 时从未发生过这种事情。
希望我的信息能被理解,主要是关于长拉刷新问题。
您的问题是您在 getData
中做的第一件事是删除 self.posts
中的所有帖子,但您没有(大概是因为缺少代码)重新加载 table 视图,所以现在数组中的帖子数 (0) 和 tableview * 认为在数组中的帖子数(不是零)不同,所以你会遇到数组边界崩溃。
在 self.posts.removeAll()
之后调用 reloadData
会解决问题,但会导致 table 视图 'flashing',因为它重新绘制为空,然后使用新数据重新绘制。
由于您没有显示 getData
的完整代码,我无法提供您需要的确切代码,但它应该类似于:
func getData() {
fetchPostsWithCompletion() {
if let tempPosts = dataFromNetwork {
self.posts = tempPosts
} else {
self.posts.removeAll()
}
self.refresh() // Dispatch this on the main queue if your completion handler is not already on the main queue
}
}
这样您就可以在获得新数据之前不操作支持数组。
我刚遇到同样的问题。我的发现是在 posts
数组上延迟 removeAll()
的执行允许 table 视图在其 count
.
func getData() {
self.delayExecutionByMilliseconds(500) {
self.posts.removeAll()
}
// queries the backend and fills the data - sorry for code omission
refresh()
}
fileprivate func delayExecutionByMilliseconds(_ delay: Int, for anonFunc: @escaping () -> Void) {
let when = DispatchTime.now() + .milliseconds(delay)
DispatchQueue.main.asyncAfter(deadline: when, execute: anonFunc)
}