On average, I have a NSMutableOrderedSet where a new custom object is added every second. Every time a new data arrives, a reference to the lastObject is updated. Also at the end of method, if NSMutableOrderedSet count is bigger than 300 first object is removed from NSMutableOrderedSet. All done in an @synchronized block.
In iOS13, we get a NSRangeException crash in 50.000 sessions. Crash Logs:
Fatal Exception: NSRangeException
*** -[__NSArrayM objectAtIndex:]: index 300 beyond bounds [0 .. 299]
0 CoreFoundation __exceptionPreprocess
1 libobjc.A.dylib objc_exception_throw
2 CoreFoundation -[__NSCFString characterAtIndex:].cold.1
3 CoreFoundation _CFDataInit
4 xxxxxx -[xxx lastObject:]
With reducing the time interval of adding data, I was able to create a crash in the test environment. Crash happens exactly in this line
MY-NSMutableOrderedSet lastObject
How can such a crash happen in a simple iOS method that returns the last object in the array.
For now, I got rid of the crash by turning the NSMutableOrderedSet into a NSMutableArray. I tested it, I can easily crash it in my test environment by turning it into a NSMutableOrderedSet. When type is NSMutableArray, it doesn't crash. I think it's a bug related to iOS 13.