- You create an NSMutableArray.
- You add the same object to it twice.
- You send the array one
removeObjectIdenticalTo:message, passing the object you added.
What is the count of the array?
If you said 1, you’re wrong.
Worse, you might think the opposite of addObject: is removeObject: (especially if you’d never heard of the …IdenticalTo: version), but that’s even more wrong: removeObject: finds the object(s) to remove by testing equality (sending them isEqual: messages), not simply searching for the object you passed in.* That means it may remove objects that aren’t the object you passed in, but are equal to it. So, unless you really do want to remove any objects equal to the one you have, you should prefer removeObjectIdenticalTo:.
But that still removes the object entirely from the array, regardless of how many times it’s there. Unless you really want that, you more probably want this:
NSUInteger idx = [myArray indexOfObjectIdenticalTo:obj];
[myArray removeObjectAtIndex:idx];
And even then, that will remove the object from the first place you added it in at, not the last, so if you specifically need to remove it from the last place you added it (LIFO instead of FIFO), then you need to enumerate the array backwards, counting an index down as you go, remove the object at the index upon finding the object, and finally break out of the loop.
To make that easy and avert the otherwise high likelihood of off-by-one errors in many independent implementations, here’s a category you can add to your projects. Use anywhere you need the opposite of -[NSMutableArray addObject:].
* This doesn’t matter for sets, since it dupe-checks every object coming in based on equality anyway. With a set, removing the equal object and removing the same object are the same thing, which is why NSMutableSet doesn’t have removeObjectIdenticalTo:. Not so for arrays, which is why NSMutableArray does. ↶










