简体   繁体   中英

cellForRowAtIndexPath crashes after being called much later than numberOfRowsInSection

I'm encountering a problem where tableView:numberOfRowsInSection: is getting called, then a other methods are getting called that affect the underlying array, then tableView:cellForRowAtIndexPath: gets called and crashes because the contents of the underlying array is different than when numberOfRowsInSection was called. If the framework would call numberOfRowsInSection right before calling cellForRowAtIndexPath , there wouldn't be a problem.

Since I can't expect a fix in the framework in the short term, the easiest solution I'm looking at is returning a dummy cell if the underlying array doesn't contain the requested entry.

More details on how this problem occurs:

  1. App uses a tab bar controller.
  2. The root controller for each tab is a UINavigationController .
  3. The view controller in question is invoked by pushing it on the nav stack of the second tab bar item's nav controller.
  4. The viewWillAppear method of the view controller in question resets the underlying array and then calls [_tableView reloadData] .
  5. The app delegate which implements UITabBarControllerDelegate implements the tabBarController:didSelectViewController: method and calls popToRootViewControllerAnimated: on the view controller being selected.
  6. The root view controller's viewWillAppear method calls a method on the view controller in question which affects the contents of the underlying array.

Steps to repro the problem:

  1. Start app.
  2. Tap second tab item.
  3. Tap to bring up view controller in question. Perform work on that view to fill the table.
  4. Tap first tab item.
  5. Tap second item.

At step five, here is the order of the calls:

  1. viewControllerInQuestion: viewWillAppear - reloads underlying array, calls [_tableView reloadData]
  2. viewControllerInQuestion: numberOfRowsInSection - returns 1
  3. App delegate: didSelectViewController - calls popToRootViewControllerAnimated
  4. secondTabBarRootViewController: viewWillAppear - calls method on viewControllerInQuestion that clears contents of underlying array
  5. viewControllerInQuestion: cellForRowAtIndexPath - crashes trying to access object at index 0 in underlying array.

Thanks for any help you can give me.

This turned out to be a problem with improper calls to reloadData on the table view. I inherited this code, but I'm new enough to iOS that I didn't understand the proper usage.

The code was calling [_tableView reloadData] in both loadView and in viewWillAppear. Removing both calls solved this particular problem.

I had a similar problem. If you have an observer in your controller that calls reloadData , use the viewWillAppear method to add the observer and viewWillDisappear to remove it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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