The Bug
Shifting an NSMutableIndexSet by a negative number will drop an index in some cases.
Example Code:
NSMutableIndexSet *set = [NSMutableIndexSet indexSetWithIndex:0]; [set addIndex:2]; [set shiftIndexesStartingAtIndex:1 by:-1]; NSLog(@"%@", set);
The set should contain 0-1 but instead contains only 1.
The Reason
NSIndexSet is a series of NSRange-s. If the shift method removes empty space between ranges, than they should become a single unified range. For example, if a set contains the range 1-2 and the range 5-6, and we do
[set shiftIndexesStartingAtIndex:3 by:-2];
then we should get a set with a single range 1-4.
However, the implementation of shiftIndexesStartingAtIndex:by: fails to unify ranges, and also assumes that separate ranges have at least one empty space between them. And so we get a set containing the ranges 1-1 and 3-4.
The Workaround
Luckily, the methods addIndex: and addIndexesInRange: do correctly unify ranges. And so the workaround is to first call one of these methods, and only then shift:
[set addIndexesInRange:NSMakeRange(3, 2)]; [set shiftIndexesStartingAtIndex:3 by:-2];