繁体   English   中英

iOS和Swift:应用程序在UITableView向下滚动事件时崩溃

[英]iOS with Swift: App crashes on UITableView scroll down event

我正在用Swift编写一个iOS应用,该应用将来自API的数据放入TableView中。 目标是用户可以向下滚动博客帖子的连续列表。 发生的情况是,数据可以很好地填充第一个屏幕的单元格数量,但是当用户向下滚动时,应用程序由于单元格属性之一而崩溃, cellImageView变为nil并且被解包(因为在单元格类的代码中指定了强制解包) ):

class BlogPostEntryCell: UITableViewCell {
    //MARK: Properites
    @IBOutlet weak var titleLabel: UILabel!
    @IBOutlet weak var bodyTextView: UITextView!
    @IBOutlet weak var initialsImageView: UIImageView!   
}

这是导致崩溃的代码:

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "NewCell", for: indexPath) as! NewCell

    apiCaller.getAPIDataThroughAsyncCall(id: nextCell, entry: { cellContent in
        DispatchQueue.main.async(execute: {
            cell.cellLabel.text = cellContent.labelText
            cell.cellTextView.text = cellContent.textViewText
            // App crashes at the below line
            cell.initialsImageView = self.createPicture(initials: cellContent.pictureText)
        })
    })

    nextCell += 1

    return cell
}

有趣的是,如果这样做:

    cell.cellLabel?.text = cellContent.labelText
    cell.cellTextView?.text = cellContent.textViewText
    // App does NOT crash at the below line
    cell.initialsImageView? = self.createPicture(initials: cellContent.pictureText)

,应用程序不会崩溃,但数据会随着用户滚动而重复一遍又一遍。

我在这里尝试过解决类似问题的解决方案: 为什么在快速滚动tableview之后,从coredata返回的数据为何变为nil? ,但这没有用。 但是,我确实认为这与异步API调用有关。

我认为可能的解决方案可能包括在生成单元之前填充一组API数据,但是在重新考虑代码的体系结构之前,我希望对此问题的来源有所了解。

您需要在viewDidLoad进行API调用,以了解其中有多少个元素并将其ID记录在数组中。 然后在您的cellForRow函数中,您可以通过这种方式获取ID

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "NewCell", for: indexPath) as! NewCell

    apiCaller.getAPIDataThroughAsyncCall(id: array[indexPath.row], entry: { cellContent in
        DispatchQueue.main.async(execute: {
            ...
        })
    })
    return cell
}

您的nextCell无法工作的原因是,每次当表视图试图显示当前不在屏幕上的单元格时,都会调用此cellForRow函数。 假设您知道您有10个元素,并且屏幕上只能显示5个元素。 当您滚动到底部时,您的nextCell将变为10,并且一切正常。 但是现在当您向上滚动时,表格视图必须再次准备前5个。 因此,现在您的nextCell变为15,您在API调用中没有相应的元素。

不好的做法是在cellForRowAt indexPath:IndexPath中调用任何API,如您所见,它会导致崩溃,请看一下MVVM。 这就像赢得一场战争而不必参加战斗一样,我指的是您在cellForRowAt indexPath中调用API的此实例:IndexPath并且出口未初始化。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM