Core Data error when deleting row in tableView - iphone

I have a UITableViewController managing a grouped tableView. The tableView is populated from a fetchedResultsController.
If I click the Edit button in the NavigationBar, then select a row and click the Delete button, the row is deleted and all ends well.
However, if I swipe to reveal the Delete button in a row and click the Delete button, the app crashes with the following error:
2010-01-06 15:25:18.720 Take10[14415:20b] Serious application error. Exception was caught during Core Data change processing: -[NSCFArray objectAtIndex:]: index (1) beyond bounds (1) with userInfo (null)
2010-01-06 15:25:18.721 Take10[14415:20b] Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[NSCFArray objectAtIndex:]: index (1) beyond bounds (1)'
Of course, the index number in the error changes depending on the number of rows in the section where I am attempting to delete a row, and that number is 1 more than the number of remaining rows in the table section after the attempted delete.
Here is the code where I attempt to delete the data from the fetchedResultsController. The same method responds to both scenarios, so I don't understand why it crashes when swiping.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the managed object for the given index path
NSManagedObjectContext *context = [fetchedResultsController managedObjectContext];
[context deleteObject:[fetchedResultsController objectAtIndexPath:indexPath]];
// Save the context.
NSError *error = nil;
if (![context save:&error]) {
/*
Replace this implementation with code to handle the error appropriately.
abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. If it is not possible to recover from the error, display an alert panel that instructs the user to quit the application by pressing the Home button.
*/
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
abort();
}
}
}
Any ideas???
Thanks
Jk

Jeff LaMarche has done some good work with NSFetchedResultsController.
Try using his template here:
http://iphonedevelopment.blogspot.com/2010/01/navigation-based-core-data-application.html
And see if that solve your issue.

One difference between normal and swipe delete is that the latter will call tableView:willBeginEditingRowAtIndexPath and tableView:didEndEditingRowAtIndexPath. In fact, that's a good way of suppressing the indentation and showing of an insert row.
Another difference is that setEditing: is called (with NO as the parameter value) immediately after the delete.
Set breakpoints in any of those three functions that you've defined/overridden and see if you can narrow down where it's happening.

Related

core data delete crash

I need to update a task before it is deleted. I found when this line [self.fetchedResultsController objectAtIndexPath:indexPath]; is executed in NSFetchedResultsChangeDelete the app crashes.
case NSFetchedResultsChangeDelete:{
Task *task = [self.fetchedResultsController objectAtIndexPath:indexPath];
[self deleleReminderForTask:task];
[self checkForUpdateForTaskForDelete:task];
[tableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
crash log:
CoreData: error: Serious application error. Exception was caught during Core Data change processing. This is usually a bug within an observer of NSManagedObjectContextObjectsDidChangeNotification. *** -[_PFBatchFaultingArray objectAtIndex:]: index (40324416) beyond bounds (1) with userInfo (null)
Can anybody help me to fix this.
The fetched results controller has already been updated so you can't try to get the item from it. Instead you should use the object that is passed as a parameter to the delegate method. You should also check what you're doing with the deleted item is you still have issues.

app crashes when deleting an object from core data in iphone

I have populated a table view with some data from server and saved it to the core data.Now i have to delete the object from the core data when the user clicks on the delete option in the table view.
What i have tried is this:`
-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
NSError *error;
[[Server serverInfo].context deleteObject:[self.couponList objectAtIndex:indexPath.row]];
if(![ [Server serverInfo].context save:&error]) {
// Handle error
NSLog(#"Unresolved error series %#, %#", error, [error userInfo]);
}
[self.couponList removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
withRowAnimation:UITableViewRowAnimationFade];
if ([self.couponList count]==0) {
[self.table setEditing:NO animated:YES];
[self.editBt setStyle:UIBarButtonItemStyleBordered];
}
}
`
But it gives an exception and crashes.This is i am getting in the log :"Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'An NSManagedObjectContext cannot delete objects in other contexts".'Can anyone solve this?Thanks in advance
you have to make some manageobject context, a fetch request and then remove object using some predicate.
Apparently you are using more than one managed object context. This is indicated by your error message. Make sure that you are using only one managed object context, i.e. that there are no background tasks that use a different one.
You are keeping the data for your table view in a separate array. This might be another problem. The proper way to deal with core data and table views is to employ the NSFetchedResultsController.
Agree with Mundi.
On top of that, if you require many instances of the managedObjectContext, do not create that many but rather use the lock and unlock functions of the NSManagedObjectContext to enable multi-threading without issues on faults and invalidation of the objects.
EDIT
Maybe you can try creating just one NSManagedObjectContext in the AppDelegate and call the same managedObjectContext from the controllers where you need to use them. This, and together with the lock and unlock methods solved my issue with the multi-threading and invalidation of the objects.
Hope this helps.

NSRangeException causing app to crash on the phone but not the emulator

First of all Im going to show you the error I am getting, then I will try to explain what I am doing to get this error etc
2011-11-02 10:17:57.665 code[1327:707] *** Terminating app due to uncaught exception 'NSRangeException', reason: '-[UITableView scrollToRowAtIndexPath:atScrollPosition:animated:]: section (0) beyond bounds (0).'
*** First throw call stack:
(0x31fe88bf 0x31d581e5 0x31fe87b9 0x31fe87db 0x32b6df1f 0x29c9b 0x32ae26b5 0x32b3daf1 0x32afed21 0x32afea71 0x32afe78b 0x32afe4ff 0x32ab581b 0x32abafb9 0x3193aba7 0x3273be8d 0x31fbb2dd 0x31f3e4dd 0x31f3e3a5 0x3204afed 0x32ace743 0x35a1 0x301c)
terminate called throwing an exception(gdb)
This is what I am doing to get this error.
Any time that I enter the subview with the dataset of indexpath[0,1] for the second time the app will throw this error.
This is the code where the error happen.
subview.m
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
//Center previously selected cell to center of the screen
[self.tableView reloadData];
[self.tableView scrollToRowAtIndexPath:oldCheckedIndexPath atScrollPosition:UITableViewScrollPositionMiddle animated:NO]; //happens on this line
}
and this is the output from that error.
What should I be looking at.. I dont really know whats good or bad from this.
Whats really frustrating is that if I go in and out of IndexPath [0,0] from the main view or any of the other ones it works fine and there is never a problem with this app..
I am hoping someone can help me, or at the very least give me an idea of what the problem might be or where.
I had a similar problem in my project where I was deleting objects from my datasource and then immediately calling [self.tableview reloadData];
What I did to solve the issue was call:
dispatch_after(DISPATCH_TIME_NOW, dispatch_get_main_queue(), ^(void){
[self.tableView reloadData];
});
This basically calls reloadData in the next run loop. You can do a similar thing using performSelector:afterDelay.
So my suggestion is try calling:
dispatch_after(DISPATCH_TIME_NOW, dispatch_get_main_queue(), ^(void){
[self.tableView scrollToRowAtIndexPath:oldCheckedIndexPath atScrollPosition:UITableViewScrollPositionMiddle animated:NO];
}
Note: You don't need to actually have a delay time specified, these 2 techniques force the method to be called at the start of the next run loop.

CoreData the save method is not working

Im a creating an app for my iPhone using coredata.
I have a viewcontroller with an object i want to save that object to my FavoriteViewController.
By clicking a button favorite I want my object to be save into the managedObjectContext but I'm getting the following error:
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Attempted to perform another operation with a fetch already in progress'. *
My Code:
// Step 1: Create Object
Favorite * newFavorite = (Favorite*)[NSEntityDescription insertNewObjectForEntityForName:#"Favorite" inManagedObjectContext:managedObjectContext];
// Step 2: Set Properties
newFavorite.name = #"Company";
NSLog(#"%#",newFavorite);
// Step 3: Save Object
NSError *error = nil;
if (![newFavorite.managedObjectContext save:&error]) { // this is where the program crash
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
abort();
}
I am not sure what I'm doing wrong.
I am going to guess you have a UI element, such as a table, that activates a fetch when the UI is changed. For example, if you have a fetched results controller, any scrolling of the table can activate the fetched results controller's fetch.
You can't mutate a collection while iterating over that collection because the count of the iteration changes while the iteration is in process. A fetch iterates over the collection of objects matching its entity and predicate. If you insert an object while the fetch is working you will get an error.
Usually you see this problem with multiple threads but I think the UI might trigger the problem in the right set of circumstances.
You have probably changed something in your tables. If this is true, try to use the original values for the table Z_METADATA (Z_VERSION, Z_UUID, Z_PLIST), Z_PRIMARYKEY (Z_ENT)...

Please help with iPhone Memory & Images, memory usage crashing app

I have an issue with memory usage relating to images and I've searched the docs and watched the videos from cs193p and the iphone dev site on memory mgmt and performance. I've searched online and posted on forums, but I still can't figure it out.
The app uses core data and simply lets the user associate text with a picture and stores the list of items in a table view that lets you add and delete items. Clicking on a row shows the image and related text. that's it.
Everything runs fine on the simulator and on the device as well. I ran the analyzer and it looked good, so i then starting looking at performance. I ran leaks and everything looked good. My issue is when running Object Allocations as every time i select a row and the view with the image is shown, the live bytes jumps up a few MB and never goes down and my app eventually crashes due to memory usage. Sorting the live bytes column, i see 2 2.72MB mallocs (5.45Mb total), 14 CFDatas (3.58MB total), 1 2.74MB malloc and everything else is real small. the problem is all the related info in instruments is really technical and all the problem solving examples i've seen are just missing a release and nothing complicated. Instruments shows Core Data as the responsible library for all but one (libsqlite3.dylib the other) with [NSSQLCore _prepareResultsFromResultSet:usingFetchPlan:withMatchingRows:] as the caller for all but one (fetchResultSetReallocCurrentRow the other) and im just not sure how to track down what the problem is. i've looked at the stack traces and opened the last instance of my code and found 2 culprits (below). I havent been able to get any responses at all on this, so if anyone has any tips or pointers, I'd really appreciate it!!!!
//this is from view controller that shows the title and image
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
self.title = item.title;
self.itemTitleTextField.text = item.title;
if ([item.notes length] == 0)
{
self.itemNotesTextView.hidden = YES;
} else
{
self.itemNotesTextView.text = item.notes;
} //this is the line instruments points to
UIImage *image = item.photo.image;
itemPhoto.image = image;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete)
{
// Delete the managed object for the given index path
NSManagedObjectContext *context = [fetchedResultsController managedObjectContext];
[context deleteObject:[fetchedResultsController objectAtIndexPath:indexPath]];
// Save the context.
NSError *error = nil;
if (![context save:&error]) //this is the line instruments points to
{
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
exit(-1);
}
}
}
I suggest you to store image URL instead of image data itself. This prevent CoreData to work with and cache big data.