According to the NSMutableArray documentation:
removeLastObject
raises anNSRangeException
if there are no objects in the array.
For some reason, I seem to be able to call this method on an empty array, and no exception is thrown.
Here's a test case:
- (void)testNSMutableArray
{
NSMutableArray* arr = [[NSMutableArray alloc] init];
STAssertTrue([arr count] == 0, @"Array count should be 0");
STAssertThrows([arr removeLastObject], @"Should throw NSRangeException");
}
This test case fails on the last line for me with the message:
[arr removeLastObject] raised (null). Should throw NSRangeException
Am I confused here? Is the documentation wrong?
Looking at the assembly, it appears this behaviour changed in Lion. Here's a portion of the implementation of [__NSArrayM removeLastObject]
(which is the actual implementation you're calling):
0x3494975a: movs r0, #7
0x3494975c: bl 0x3490c26c ; _CFExecutableLinkedOnOrAfter
0x34949760: cbz r0, 0x3494977c ; -[__NSArrayM removeLastObject] + 60
This calls CFExecutableLinkedOnOrAfter
with a value of 7; if that returns 1 (which it does on my machine), you get the behaviour you're seeing. If it returns 0, you get an exception.
CFExecutableLinkedOnOrAfter
is an undocumented function, but some snooping around suggests that it returns if the executable is linked after a particular version of Mac OS X. Some more snooping suggests that the value of 7 corresponds to 10.7.
So, if you're running Lion or later, you won't get an exception. Sounds like a doc bug to me!
You are right, the documentation seems wrong (or probably outdated) in this case. NSRangeException is thrown when we try to access an object at some index i, which is not present in the array. But in [arr removeLastObject], I guess iOS is automatically checking to ignore the case when the array is empty
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With