2

I am currently developing a Core Data application. I have a table view that shows a list of items whose attribute scheduled (which is a date) is nil and a BOOL attribute is NO. There is a button in each of the table view cells that allows the user to set the date in a modal view. There is a date picker in the modal view. The item is passed to that modal view controller.

The date is set when the user taps the Done button in the modal view. The date is set with this line of code:

self.item.scheduled = self.datePicker.date;

Apparently this line of code causes the UI to be blocked for ~1 second (on a 5th generation iPod touch), which is undesired behavior. I used Instruments and discovered that -[NSManagedObjectContext(_NSInternalChangeProcessing) _processRecentChanges:] took over 900.0ms.

Can someone please enlighten me as to what is causing the slowness? I am using just one MOC at the moment. Am I supposed to use another to make the change?

Edit: The method that took the longest time I got from Instruments tells me that the table view controller seems to have tried to re-fetch or update the cell, causing the slowness. I have -com.apple.CoreData.SQLDebug 1 passed on launch though, but no message was shown when the date was set.

This is the call tree I got from Instruments.

Call tree

CoreDataTableViewController is taken from a book about Core Data that I read. It is mostly the same as the one found here.

vp5
  • 438
  • 6
  • 17
  • Try `NSDate* myDate = self.datePicker.date; self.item.scheduled = myDate;` and see which line is slower? – Pang Jun 22 '14 at 03:20
  • @Pang Tried it, the UI is still blocked. The method that took the longest time I got from Instruments tells me that the table view controller seems to have tried to re-fetch or update the cell, causing the slowness. I have `-com.apple.CoreData.SQLDebug 1` passed on launch though, but no message was shown when the date was set. What gives? – vp5 Jun 22 '14 at 09:31
  • 1. You should update your question with your latest findings. 2. Setting a property does not run any SQL until you commit. 3. Check if `self.item.scheduled = self.datePicker.date;` is run for unexpectedly many times. 4. Provide more info for people to help, e.g. the call stack in instruments causing the slowness. – Pang Jun 22 '14 at 09:38
  • 1. `CoreDataTableViewController` seems not part of Apple's API so please state where it comes from ([here](https://github.com/Agent007/FlickrFetcher/tree/master/FlickrFetcher) or [here](http://web.stanford.edu/class/cs193p/cgi-bin/drupal/node/167) or what)?. 2. State your test environment (iOS version, hardware or simulator model) and try testing on different environments, 3. Not sure what's in `-[UIView(AdditionalLayoutSupport) _switchToLayoutEngine:]` but try simplifying the layout of your `UITableViewCell`. – Pang Jun 23 '14 at 01:24
  • 4. Try disabling animation by changing `UITableViewRowAnimationFade` to `UITableViewRowAnimationNone` in [`-controller:didChangeObject:atIndexPath:forChangeType:newIndexPath`](https://github.com/Agent007/FlickrFetcher/blob/master/FlickrFetcher/CoreDataTableViewController.m#L134-L149). Hope I or somebody can help you. – Pang Jun 23 '14 at 01:25

1 Answers1

2

I finally found the answer. It turns out Auto Layout is extremely slow when offscreen. This is why it can be seen in the call tree that the layout operation took the majority of time.

The solution I chose was to remove the table view controller as the NSFetchedResultsController's delegate in viewWillDisappear:. Then, in viewWillAppear:, I perform a re-fetch and call reloadData on the table view, and set the NSFetchedResultsController's delegate property back to self (which is the table view controller).

EDIT: As amb mentioned in the comments, the solution above is a bad approach. This is the better approach. I should add that my table view only correctly reloaded when I added

if(self.tableView.window == nil)
    return;

also to controllerWillChangeContent:.

Community
  • 1
  • 1
vp5
  • 438
  • 6
  • 17
  • 1
    This is a bad approach. Instead, try this: http://aplus.rs/2014/one-not-weird-trick-to-save-your-sanity-with-nsfetchedresultscontroller/ – amb Jun 26 '14 at 13:45
  • Thank you very much for the better approach. I've edited the answer – vp5 Jun 27 '14 at 05:41