I’ve created an array of objects in the main app delegate that is loading data from an sqlite database. When I load the TableView, a property in this class is set to point to the array of objects. Then, as the TableView is displayed it correctly returns the count of the array for the number of rows and displays the text in the cell from a property of the appropriate object in the array.
I also have a refresh button in the top-right corner of the navigation bar which goes out and downloads an XML file from the network, parses it, and then updates the database.
I then recreate the main array of objects from the database and point my TableView property to the new array and then ask the TableView to reload the data. This is where it then crashes with a EXC_BAD_ACCESS.
I have stepped through with the debugger and determined that everything is correct up until the reloadData call. The database and main array are both synchronised and the custom TableView property is also pointing to the main array.
Then, as I step through with the debugger, I noticed a couple of things. Firstly, when it calls numberOfRowsInSection, the pointer to the main array is correct and the number of rows is correct. Secondly, when it gets to the first cellForRowAtIndexPath call, the pointer to the main array is pointing to an invalid section of memory. The actual memory address is the same but the array of objects has disappeared.
I cannot understand how the array disappears in the middle of the reload like this because my reference count should still be greater than zero so there should be no garbage collection. So my question is, does anybody have any idea what might be happening? And secondly, how do I determine the exact location of the problem?
You are almost certainly under-retaining the array. When you say “my reference count should still be greater than zero,” it almost certainly is not. If it were, it would not have been released.
Start by looking for any place you directly access ivars. This is the #1 cause of memory management errors. Access ivars only through accessors (
self.thing) except in dealloc and init. This will solve 90% of these kinds of problems.