iosobjective-cxcodenssetnsrangeexception

NSMutableOrderedSet lastObject NSRangeException crash


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.


Solution

  • 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.