One thing I really don't like about Objective-C is that it's very difficult to find out what's going on under the hood.
The latest problem this has caused me is a random exception that occurs in random places in my code and breaks everything - it's the one listed above, about concurrency problems with NSArray.
The thing is that I never use NSEnumerator myself, instead if I do iterate through an array I do it like this:
for (int i = 0; i < [array count]; i++)
{
id obj = [array objectAtIndex:i];
//blah blah
}
The question is whether or not some Obj-C code creates an NSEnumerator under the hood and I just can't tell, or whether I should spend hours tracing through my code trying to figure this one out.
Any of the following could potentially be called on the array:
objectAtIndex:
exchangeObjectAtIndex: withObjectAtIndex:
replaceObjectAtIndex: withObject:
It doesn't seem like any of those, since they are index operations, should require enumerators. But do they? Do any of the functions in NSMutableArray?
Also, I am indeed using two threads in my program - and when I added in the other thread the problem started. I just don't want to mess around with putting locks and things in my code until I know exactly where the problem is.
PLEASE don't give me some comment telling me I'm lazy, that's not the question here. I will put in locks and better thread safety if first know the problem is from my end. I don't want to waste time doing all that if it's because of Apple's API. The question is whether or not it is in fact from my end. That's it. I want to know when NSArray creates an NSEnumerator.
Jerret Hardy gets the win for this one: http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/Multithreading/ThreadSafetySummary/ThreadSafetySummary.html provides a reasonable explanation that I simply can't use NSMutableArray in multiple threads. Fair enough, I guess.
EDIT: Looks like the problem was being caused by [NSMutableArray addObject:], which was being called in another thread while [NSMutableArray objectAtIndex:] was being called. The generated NSEnumerator exception was throwing me off - if anyone else gets this exception then they should check for any concurrent NSMutableArray access and mutation that can occur in their program, with or without NSEnumerator being involved.