0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

When you call reloadSections or reloadRowsAtIndexPaths, the "invalid number of rows in section *." exception occurs.

Posted at

These codes below are one example the exception occurs.
以下は、それを再現する一例です。

class TableViewReloadViewController: UITableViewController {
    
    private var didReload = false
    
    override func viewDidLoad() {
        super.viewDidLoad()
        self.tableView.estimatedRowHeight = 10
        self.tableView.rowHeight = UITableViewAutomaticDimension
    }

    // MARK: - Table view data source

    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 2
    }

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        print("@@@ numberOfRowsInSection. section=\(section)")
        switch section {
        case 0:
            //let count = 1
            let count = self.didReload ? 2 : 1 // [*1]
            print("@@@ numberOfRowsInSection. section0. count=\(count)")
            return count
        case 1:
            let count = 1
            //let count = self.didReload ? 2 : 1 // [*4]
            return count
        default:
            return 0
        }
    }

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        print("@@@ cellForRowAtIndexPath. section=\(indexPath.section)")
        switch indexPath.section {
        case 0:
            let cell = tableView.dequeueReusableCellWithIdentifier("cell0", forIndexPath: indexPath)
            return cell
        case 1:
            let cell = tableView.dequeueReusableCellWithIdentifier("cell1", forIndexPath: indexPath)
            if !self.didReload {
                self.didReload = true // [*2]
                dispatchAsyncMain({
                    print("@@@ reloadRowsAtIndexPaths. section=\(indexPath.section), row=\(indexPath.row)")
                    // NOTE:
                    //  This exception below occurs.
                    //  ```
                    //  *** Assertion failure in -[UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit_Sim/UIKit-3318.16.14/UITableView.m:1582
                    //  *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of rows in section 0.  The number of rows contained in an existing section after the update (2) must be equal to the number of rows contained in that section before the update (1), plus or minus the number of rows inserted or deleted from that section (0 inserted, 0 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out).'
                    //  ```
                    //
                    //  ## There was caused that,
                    //  1. The [*1] count = 1. (section: 0)
                    //  2. The [*2] didReload changes from false to true.
                    //  3. The [*3] reloadSections executes. (section: 1)
                    //  4. The [*1] count changes from 1 to 2. (section: 0)
                    //  5. The exception occurs.
                    //  * If you implement [*4] instead of [*1], the exception doesn't occurs.
                    self.tableView.reloadSections(NSIndexSet(index: indexPath.section), withRowAnimation: .Fade) // [*3]
                })
            }
            return cell
        default:
            return UITableViewCell()
        }
    }
}
0
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?