NSFetchedResultsController fetchedObjects changing?
NSFetchedResultsController fetchedObjects changing?
- Subject: NSFetchedResultsController fetchedObjects changing?
- From: Abhi Beckert <email@hidden>
- Date: Sat, 11 Dec 2010 10:45:29 +1000
Hi,
I have a UITableView, with a datasource using array of NSDictionary objects for the view (it used to be more complicated, but I've changed it to track down a bug).
I have a single method which builds the array of dictionary's:
- (void)reloadInspectionResults
{
if (dispatch_get_current_queue() != dispatch_get_main_queue()) {
@throw [NSException exceptionWithName:@"call from wrong thread" reason:@"Tried to reload inspection data from a background thread." userInfo:nil];
}
self.inspectionsResultsController = /* allocate/configure/execute fetch */
self.inspections = inspectionsResultsController.fetchedObjects;
self.tableViewContent = [NSMutableArray array];
for (Inspection *inspection in self.inspections) {
[self.tableViewContent addObject:[NSDictionary dictionaryWithObjectsAndKeys:inspection.display_name, @"display_name", inspection.display_inspection_datetime, @"display_inspection_datetime", [inspection objectID], @"objectID", nil]];
}
[self.inspectionsView reloadData];
[self.inspectionsView setNeedsDisplay];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.tableViewContent.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
/* return a new cell, filled with values from self.tableViewContent */
}
I have a background thread, which downloads data from the server and updates the contents of the managed object context, and informs my table view to reload it's data. When the user tap's a row in the UITableView, I'm doing this:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(@"%@", self.inspections);
NSLog(@"%@", self.tableViewContent);
NSManagedObjectID *objectID = [[self.tableViewContent objectAtIndex:indexPath.row] valueForKey:@"objectID"];
Inspection *inspection = (Inspection *)[[MOC mainContext] objectWithID:objectID];
/* do stuff with inspection object, which is often the wrong object by one index, or crashes if the last item was tapped */
}
For days we've been tracking down an edge case bug where tapping a row in the UITableView either opens the wrong item or crashes. I don't fully understand what's going on, but when an item is removed from the array, the UITableView does not see the new data, even though the *only place* where this array is created immediately reloads the data and tries to trigger drawRect via setNeedsDisplay.
Sometimes it takes 10 or 20 minutes for the UITableView to correctly remove the item from the list. This is dependent on a background thread which uploads JPEG data over 3G. Activating airplane mode while it's uploading the JPEG causes the bug to stick around indefenently. The table view continues to show draw the wrong data even after pushing a new view controller, doing stuff which will trigger low memory warnings (taking photos, doing lots of stuff with the new NSImage, etc), and going back to this view (causing the reloadInspectionResults to be triggered *again* due to low memory warning).
Reading online, I've seen suggestions that this kind of stuff will be caused if you try to reload the table view from a background thread. As you can see, I added my own exception to check for that — this exception is never triggered.
The array is definitely not modified in any other place. I only defined that instance variable while trying to track down this bug.
Tapping the last item in the view while it's out of sync will crash the app. Tapping any other item in the view will cause the wrong database record to be opened, this is currently causing employees of our client to enter data into the wrong database record, triggering invalid documents to be sent to other businesses. By government regulation, our client is legally required to distribute these documents within 48 hours of collecting the data, which is now impossible and causing major trust issues.
Does anyone have any ideas? I've run out, and am planning to move all network activity to the main thread (even though it may have to upload a several megabytes over 3G), to workaround this bug.
- Abhi_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden