Question

I have an NSOperationQueue whose operations are constantly manipulating the instance variable myMutableArray in the background (both adding and removing elements). maxConcurrentOperationCount is set to 1, so there should never be more than one operation manipulating the array at the same time.

myMutableArray is used in an NSTableView's data source methods as well. [tableView reloadData] is being called on the main thread by each individual NSOperation after it has finished manipulating myMutableArray.

Now for my problem: Occasionally, I get the following exception:

-[__NSArrayM objectAtIndex:]: index 0 beyond bounds for empty array

from within tableView:objectValueForTableColumn:row:.

I don't understand why exactly this can occur when I am running my operations one at a time. What can I do to prevent it from happening?

Was it helpful?

Solution

The main thread and the background thread are still both running at the same time. The reload of the table view is also not synchronous when you call reloadData. So at some point in time you request a reload when there is one item in the array, but between the row count being taken and the row cell being requested that item gets removed from the array.

Ideally, both threads shouldn't edit the same array. The background thread should take a copy of the array and edit that. Once the edit is complete, the background thread should push the whole new array back to the main thread and wait for that method to complete.

Create a new method which allows the array to be updated and which, after saving the new array, reloads the table. Call that method with:

[... performSelectorOnMainThread:... withObject:... waitUntilDone:YES];

OTHER TIPS

You could wrap any code that manipulates the data structure in an @synchronize directive which ensures only one thread can access at a time.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top