行问题的应用程序崩溃(tableView,Swift)

时间:2017-10-08 13:40:07

标签: ios swift uitableview

我有一个带有tableView的viewController。当应用程序运行时,它会因错误而崩溃:

  

由于未捕获的异常'NSInternalInconsistencyException'而终止应用程序,原因:'尝试将第0行插入第0部分,但更新后第0部分只有0行'

Rhis是viewController代码的一部分:

import UIKit
import MapKit
import CoreLocation
import GoogleMaps
import GooglePlaces
import Social
import AVFoundation

private let resueIdentifier = "MyTableViewCell"

extension UIViewController {
    func present(viewController : UIViewController, completion : (() -> ())? = nil ){
        if let presented = self.presentedViewController {
            presented.removeFromParentViewController()
        }
        self.present(viewController, animated: true, completion: completion)
    }
}

class CourseClass2: UIViewController, UITableViewDelegate, UITableViewDataSource {
    @IBOutlet weak var tableView: UITableView!

    let minimumSpacing : CGFloat = 15 //CGFloat(MAXFLOAT)
    let cellWidth: CGFloat = 250
    var category : QCategoryy?
    var places: [QPlace] = []
    var isLoading = false
    var response : QNearbyPlacesResponse?
    var rows = 0

    override func viewDidLoad() {
        super.viewDidLoad()
        self.title = category?.name
    }

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

        determineMyCurrentLocation()
    }

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

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        rows = 0
        tableView.reloadData()
        insertRowsMode3()
        category?.markView()
    }

    @IBAction func refreshTapped(_ sender: Any) {
        rows = 0
        tableView.reloadData()
        insertRowsMode3()
    }

    func insertRowsMode2() {
        for i in 0..<places.count {
            insertRowMode2(ind: i, usr: places[i])
        }
    }

    func insertRowMode2(ind:Int,usr:QPlace) {
        let indPath = IndexPath(row: ind, section: 0)

        rows = ind + 1
        tableView.insertRows(at: [indPath], with: .right)
    }

    func insertRowsMode3() {
        rows = 0
        insertRowMode3(ind: 0)
    }

    func insertRowMode3(ind:Int) {
        let indPath = IndexPath(row: ind, section: 0)
        rows = ind + 1
        tableView.insertRows(at: [indPath], with: .right)

        guard ind < places.count-1 else { return }
        DispatchQueue.main.asyncAfter(deadline: .now()+0.20) {
            self.insertRowMode3(ind: ind+1)
        }
    }

    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return  places.count    /*  rows   */
    }

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

        let place = places[indexPath.row]
        cell.update(place: place)

        if indexPath.row == places.count - 1 {
            loadPlaces(false)
        }

        return (cell)
    }

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        tableView.deselectRow(at: indexPath, animated: true)

        UIView.animate(withDuration: 0.2, animations: {
            let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! MyTableViewCell
        })

        performSegue(withIdentifier: "goToLast" , sender: users[indexPath.row])
    }

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 100
    }

    func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
        return true
    }

    func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
        if editingStyle == UITableViewCellEditingStyle.delete {
            places.remove(at: indexPath.row)
            tableView.deleteRows(at: [indexPath], with: .fade)
        }
    }
}

添加断点我看到崩溃在这个函数中:

func insertRowMode3(ind:Int) {
    let indPath = IndexPath(row: ind, section: 0)
    rows = ind + 1
    tableView.insertRows(at: [indPath], with: .right)

    guard ind < places.count-1 else { return }
    DispatchQueue.main.asyncAfter(deadline: .now()+0.20) {
        self.insertRowMode3(ind: ind+1)
    }
}  

正好在这一行:

tableView.insertRows(at: [indPath], with: .right)

我知道必须首先更新我的UITableViewDataSource然后插入行,但我不知道如何以及我必须修改以解决问题。

2 个答案:

答案 0 :(得分:0)

你必须使用begin&amp;在更改之前和之后结束更新方法。

tableView.beginUpdates()
// your modifications to the tableView
tableView.endUpdates()

告诉tableView在此期间停止将dataSource与实际的tableView匹配。

答案 1 :(得分:0)

对于传递给insertRows的每个索引路径,您需要向places数组添加相应的对象。在告诉表视图有关行的任何更改之前,数据模型需要是最新的。

请注意,在commit editingStyle方法中,您在告知表格视图删除行之前正确更新places

您的insertRowsMode[2|3]方法需要做同样的事情,当然您需要向places添加值。