Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NSMutableArray removeLastObject Exception

According to the NSMutableArray documentation:

removeLastObject raises an NSRangeException 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?

like image 350
Zach Avatar asked Feb 07 '13 20:02

Zach


2 Answers

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!

like image 192
Jesse Rusak Avatar answered Sep 20 '22 05:09

Jesse Rusak


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

like image 31
Dhruv Goel Avatar answered Sep 18 '22 05:09

Dhruv Goel