cellForRow(at:indexPath)返回nil并崩溃我的swift应用程序

时间:2017-02-06 20:47:44

标签: ios swift uitableview swift3 tableviewcell

在我的swift应用中,我在UITableView中显示了单元格,前10个单元格包含一张照片。我决定为每个单元格添加一个视差效果,这样当用户上下滚动表格时 - 图像会改变它的偏移量。

这是我从我的webservice获取数据并最初将其添加到tableview的方法:

func makePostQueryForFetchingData(_ parameters: [String:AnyObject], url: String, type: String)
{
    Alamofire.request(url, method: .post, parameters: (parameters), encoding: JSONEncoding.default)
        .validate()
        .responseJSON { response in

            switch response.result {
            case .success:
                DispatchQueue.main.async(execute: {
                    items.removeAllObjects()
                    tview.reloadData()
                    if let jsonData = response.result.value as? [[String: AnyObject]] {
                        for singleJSON in jsonData {
                            if let single = SingleNode.fromJSON(JSON(singleJSON)){
                                    self.items.add(single)
                            } 
                        }
                    }  
                    self.refreshController.endRefreshing()
                    print("before crash")
                    self.tview.reloadData()
                    print("end")
                })
            case .failure(let error):
               print(error)
            } 
    }
}

当我在启动时运行此功能时 - 一切正常。但是,如果我向下滚动表格,然后快速向上滚动并拉动刷新 - 应用程序崩溃。

在拉动刷新时我从上面调用函数。

处理视差效果的功能如下:

override func scrollViewDidScroll(_ scrollView: UIScrollView) {
    if (scrollView == self.tview) {
        for indexPath in self.tview.indexPathsForVisibleRows! {
            if (indexPath.row < 10) {
                print(indexPath)
                print(self.tview.cellForRow(at: indexPath))
                self.setCellImageOffset(cell: self.tview.cellForRow(at: indexPath) as! BigDetailsOnListCell, indexPath: indexPath as NSIndexPath)
            }
        }
    }
}

我意识到当我快速滚动桌面并刷新它时 - 我在控制台中看到了:

before crash
0
nil
fatal error: unexpectedly found nil while unwrapping an Optional value

那么为什么self.tview.cellForRow(at: indexPath)会返回nil?

4 个答案:

答案 0 :(得分:7)

如果tableview当前具有该行的可见单元格,则

cellForRow(at:)将仅返回一个单元格。如果没有可见的单元格,它将不会调用您的表格视图的数据源方法来获取单元格,它将返回nil

您需要处理cellForRow(at:)可能返回零的事实。不要强行拆开它。使用条件展开。与indexPathsForVisibleRows类似;也没有充分理由强行打开这个价值。

override func scrollViewDidScroll(_ scrollView: UIScrollView) {
    if (scrollView == self.tview) {
        if let visiblePaths = self.tview.indexPathsForVisibleRows {
            for indexPath in visiblePaths {
                if (indexPath.row < 10) {
                   if let cell = self.tview.cellForRow(at: indexPath as? BigDetailsOnListCell) {
                    self.setCellImageOffset(cell: cell, indexPath: indexPath as NSIndexPath)
                }
            }
        }
    }
}

答案 1 :(得分:1)

indexPathsForVisibleRows中的索引不会向您提供已经显示过该单元格的任何警示。请注意“可见行”“显示的单元格”之间的区别。可见行意味着滚动位置使得行显示或显示。它基于可见性计算。另一方面,cellForRow(at:)基于当前作为子视图添加的单元格。

在实际显示单元格之前,cellForRow(at:)仍然可以返回nil

这可以在调用reloadTable()或滚动后立即发生。

答案 2 :(得分:0)

在pullToRefresh方法中,将yourArray设为nil,当你得到响应时,它将填充新数据。

答案 3 :(得分:0)

我不知道这对任何人都有帮助,但这对我来说很重要。

override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)

        self.view = nil
    }

这是解决我问题的一段代码。我发送新版本后,我遇到了一个问题。问题在于,这个错误迫使应用程序在这行代码中崩溃:

let guard let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as? YourCustomTableViewCell else {...}

我发现当我尝试快速切换视图时,总是会发生崩溃(我可以切换视图,因为它们位于标签栏控制器中)。