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 protected])
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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com
This email sent to [email protected]