Following steps result in a crash in NSFetchedResultsController.
I try to add the first element to a NSFetchedResultsController backed TableView.
I create a temporary MO object and display a Modal View pane to add new object.
On the Add Sheet (a Modal View Controller), I press Cancel Button to discard the new element.
In the CancelAction callback for Cancel button, I delete the new temporary object I created.
The code till here is exactly similar to Apple sample code for Core Data. The only extra code I have is a call to [tableView reloadData] after the Add sheet is dismissed.
The crash results only if I try to add the first element, since it is related to wrong section count in NSFetchedResultsController.
This results in a crash given below. If I remove redundant call to reloadData, the crash is not visible. If I add a reloadData call to Recipe sample code data, the crash happens there as well.
Is it a known problem with NSFetchedResultsController?
2009-09-13 18:22:45.600 Recipes[14926:20b] * Terminating app due to uncaught exception 'NSRangeException', reason: '* -[NSCFArray objectAtIndex:]: index (0) beyond bounds (0)'
As you discovered by yourself, you should NOT use [tableView reloadData], because you are probably using the NSFetchedResultsController delegate methods
– controllerWillChangeContent:
– controller:didChangeObject:atIndexPath:forChangeType:newIndexPath:
– controller:didChangeSection:atIndex:forChangeType:
– controllerDidChangeContent:
These methods are actually in charge of updating your table view when you add, delete or modify objects. Therefore, when you add the call to [tableView reloadData] what happens is that two different threads are both accessing/modifying your table view. This causes the crash you are experiencing.
If you are not using the delegate methods, then the crash is due to something else in your code.
Related
I am new to ios development and I am trying to create a simple test app that allows users to record and edit their pills in their medicine cabinet.
I am using ios 6.1, arc and segues.
Background to the error:
So the user has a list of pills in their medicine cabinet, he picks one and a segue brings him to a view controller that gives him information about that pill. He then has the option to edit the info which segues him to another view controller that shows all the current info in textfields which he can edit and then click a save button which initiates an unwind segue to the original medicine cabinet.
The error I am getting is this. The user can edit the info and save it successfully and pop back to the cabinet. But then when he goes to edit the pill again, I get the error:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFString appendString:]: nil argument'
I did some digging and I found out what is happening. In the unwind segue method,I am successfully setting the properties of the pill to match the text in the textfield of the editPillView controller. For example, I have a pill and it belongs to Jay. But then I edit it and say it belongs to Raf. Using breakpoints, I can see the string change from Jay to Raf in the unwind segue method of the MedicineCabinetViewController. But once the unwind segue is complete, I see that at some point, the string gets set to nil in apple's code (probably because arc is deallocing memory because the EditPillViewController is no longer needed and the pill's owner property then becomes a null pointer). Then when the user clicks the pill again, the pillInfoViewController is trying to use the null pointer and BOOM.
I've tried so many solutions to try to keep the string to stay raf such as using the NSString copy method. Any ideas?
When you do an unwind segue, any controllers from the one you're unwinding from, back to but not including the one you're unwinding to, will be deallocated unless you have a strong reference to them. So, the pill's owner property, if it's in MedicineCabinetViewController, will go away when the controller is deallocated.
There are several ways you can fix this problem. One way, would be to navigate in your app using code rather than using segues, so you can keep references to the controllers you create, and only allocate one if it doesn't exist yet.
Another way would be to have a model class that's a singleton, which would live for the life of the app. That way all the data concerning the medicines would be properties of some object (or objects) in this singleton class.
Given this Core Data Model: Photographer <-->>Photos.
After adding a Photographer via a Modal View, the tableView of Photographers updates accordingly.
The problem is, that it doesn't do the same for Photos. I can add a Photo via a Modal View, and the tableView of Photos for that particular Photographer does not update immediately. Once I navigate back to the tableView of Photographers and select the same Photographer again, it updates as expected.
How can I get the tableView of Photos to update as soon as the Modal View(where the user added the object) gets dismissed?
Where modal view dismiss try to use:
[tableView reloadData];
Try
[tableview reload];
method after getting new data.
Check your error variable if it contains an error.
You directly assign the result of -executeFetchRequest:error: to an ivar (photographerPhotosArray). This either leaks or causes an immediate release.
Consider switching to NSFetchedResultsController since it helps you a lot.
Check your array first is it fill or empty? try with NSLog and check it. if it exist then reload your table
I have created a window based application with the following
a TableViewController (Without a XIB file)
a ViewController (With a XIB file) <-- to be used as modal view
a CoreData model to store some data
I managed to load the application and populate the TableView with the data from the Entity, and I was able to scroll through all of the cells of the TableView, without any issues.
I added a UIBarButton item (rightBarButton) that causes a Modal View to appear for the user to input some data. The model view has a SAVE and CANCEL buttons.
The problem is once I press the Cancel Button, I go back to the TableView but if I try to scroll throgh the items in the tableview, the app crashes.
After 4 hours of searching Google and StackOverflow, I was not able to see why my app crash. I did however notice by the debugger that the ManagedObjectContext is set to NIL the second time I scroll the tableview (after the modalview is dismissed), although no data is changed and no insertion/deletion occured.
I tried using a timer to call reloadData as I found some answers on StackOverflow, but that did not work. I tried setting the ManagedObjectContext as a property with retain and removed all occurences of [myManagedObjectContext release] to avoid releasing it earlier than needed, but that did not help.
It seems that I am doing an obvious mistake, but I am not sure where.
Please help.
ivars do not become nil just because they're released somewhere else (at least not in iOS 4.3). So an over-release is not the specific cause of myManagedObjectContext becoming nil. Assuming you're using accessors to reference your ivars (and you should be), hand-implement setManagedObjectContext: and put a breakpoint in there to see who's calling it. Alternately, you can add a gdb watchpoint to myManagedObjectContext to see when the memory is changed.
You haven't indicated what the crash stack is when you crash. You should be focused on what memory you're accessing at the point of the crash, and ensuring that the crash is due to a memory violation rather than an exception. Check your debugger output. Often it will tell you what's happening.
For the life of me, I cannot figure this out.
Here's the scenario:
I have a tableview with a searchbar at the top.
I do a search.
I tap a search scope button.
Do another search.
Tap the other search scope button (the one that was selected by default).
Do another search.
Crash
I'm presented with the following:
*** -[CALayer retain]: message sent to deallocated instance 0x4c7fa20
and it points to the following line of code:
[self.tableView reloadData];
I'm not releasing the array I use for the tableview data until the file's dealloc method.
Any ideas? I'm at a loss here. :confused:
Try setting NSZombieEnabled. That should give you a handle on exactly what is being over-released.
Check that all the objects you're using in and around the search are not autoreleased objects - things like [NSDate date] etc. that can get autoreleased.
Maybe post some code showing your search ?
I'm using Core Data and KVO to look for changes in values to trigger saves to the data store. I have a table view with search hooked up to NSFetchedResultsController. When the search changes, a new results controller is made on pressing the Search button. When the user selects an item in the results table view, then the user enters a detail view and can make edits.
This is where I encounter the problems. When the user makes a change in a separate UIControl that I made, the detail view is notified and can use the NSFetchedResultsController it remembers from when the table view pushed me onto the view stack to get the NSManagedObjectContext and do a save. When I do so, I sometimes get the following error:
Serious application error. Exception was caught during Core Data change processing. This is usually a bug within an observer of NSManagedObjectContextObjectsDidChangeNotification. no object at index 89 in section at index 0 with userInfo (null)
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'no object at index 89 in section at index 0'
I found that this tends to happen when I do a search and an object that isn't on the top of the table is moved up to the top. I vaguely know what might be wrong in the back of my head, but would appreciate any pointers as to how to fix this.
I figured out what was wrong. I forgot to unset the old NSFetchedResultsController's delegate, and also forgot to release said NSFetchedResultsController. My UITableView subclass also responded to updates to the NSFetchedResultsController through delegates, and caused weird calls to be made.