Reputation: 438
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.
CoreDataTableViewController
is taken from a book about Core Data that I read. It is mostly the same as the one found here.
Upvotes: 2
Views: 142
Reputation: 438
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:
.
Upvotes: 2