致命错误:刷新表视图时索引超出范围 [英] 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] .postTitle
如果我按如下所示打印帖子数和indexPath:
打印("posts.count =(posts.count)") print("indexPath.row =(indexPath.row)")
当我以正常方式下拉时,它会打印正确的数据,但是如果我像长拉一样下拉,则当崩溃时会在整个屏幕上提示
posts.count = 0
indexPath.row = 2
使用refreshControl时,这种事情从未发生过,就像我在这里使用的方式一样.
希望我的信息是可以理解的,主要是为了解决问题.
您的问题是,您在getData
中要做的第一件事是删除self.posts
中的所有帖子,但您没有这样做(大概是因为代码是丢失)重新加载表格视图,因此现在数组中的帖子数(0)和表格视图*认为在数组中的帖子数(不为零)不同,所以您会遇到数组边界崩溃的情况.>
在self.posts.removeAll()
之后调用reloadData
将解决此问题,但由于表视图重新填充为空,然后重新填充新数据,因此导致闪烁".
由于您没有显示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
}
}
这样,在拥有新数据之前,您不会操纵后备阵列.
I've this weird app crash when pulling to refresh occurs.
My code goes as it follows:
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()
}
The app runs properly and even when I pull down to refresh, everything runs perfectly, but if do a long pull down to refresh, like pulling down almost hitting the bottom of the screen, the app crashes and prompts the following error:
fatal error: Index out of range
on the line
cell.titleLabel.text = posts[indexPath.row].postTitle
If I print the post count and the indexPath as follows:
print("posts.count = (posts.count)") print("indexPath.row = (indexPath.row)")
When I'm pulling down in the normal way, it prints the correct data, but if I pull down like a long pull, through the whole screen if prompts this when it crashes
posts.count = 0
indexPath.row = 2
This kind of thing has never happen to me using the refreshControl the way I'm using here.
Hope my information is understandable, mostly on the long pull to refresh issue.
Your problem is that the first thing you do in getData
is remove all of the posts from self.posts
, but you do not (presumably since code is missing) reload the table view, so now the number of posts in the array (0) and the number of posts that the tableview *thinks is in the array (not zero) is different, so you get an array bounds crash.
Calling reloadData
after self.posts.removeAll()
would fix the issue but result in the tableview 'flashing' as it redrew empty and then redrew with the new data.
Since you haven't shown the full code for getData
I can't provide the exact code you need, but it should be something like:
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
}
}
This way you don't manipulate the backing array until you have the new data.
这篇关于致命错误:刷新表视图时索引超出范围的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!