开发者

cellForRowAtIndexPath crashes after being called much later than numberOfRowsInSection

开发者 https://www.devze.com 2023-01-24 06:14 出处:网络
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: ge

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开发者_Python百科 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.

0

精彩评论

暂无评论...
验证码 换一张
取 消