NSMutableArray removeLastObject Exception

时间:2013-02-07 20:38:33

标签: objective-c cocoa-touch exception nsmutablearray

根据NSMutableArray documentation

  如果数组中没有对象,

removeLastObject会引发NSRangeException

出于某种原因,我似乎能够在空数组上调用此方法,并且不会抛出任何异常。

这是一个测试用例:

- (void)testNSMutableArray
{
    NSMutableArray* arr = [[NSMutableArray alloc] init];
    STAssertTrue([arr count] == 0, @"Array count should be 0");
    STAssertThrows([arr removeLastObject], @"Should throw NSRangeException");
}

此测试用例在最后一行失败,并显示以下消息:

  

[arr removeLastObject] raise(null)。应抛出NSRangeException

我在这里感到困惑吗?文档错了吗?

2 个答案:

答案 0 :(得分:5)

查看程序集时,Lion中的行为似乎已更改。以下是[__NSArrayM removeLastObject]的实现的一部分(这是您正在调用的实际实现):

0x3494975a:  movs   r0, #7
0x3494975c:  bl     0x3490c26c                ; _CFExecutableLinkedOnOrAfter
0x34949760:  cbz    r0, 0x3494977c            ; -[__NSArrayM removeLastObject] + 60

这会将CFExecutableLinkedOnOrAfter调用为值7;如果返回1(它在我的机器上执行),您将获得您所看到的行为。如果它返回0,则会出现异常。

CFExecutableLinkedOnOrAfter是一个未记录的函数,但有些snooping around表示如果可执行文件在特定版本的Mac OS X之后链接,则会返回。有些more snooping表示值为7对应10.7。

因此,如果您正在运行Lion或更高版本,则不会出现例外情况。对我来说听起来像是一个doc bug!

答案 1 :(得分:1)

你是对的,在这种情况下,文档似乎是错误的(或可能是过时的)。当我们尝试访问某个索引i处的对象时抛出NSRangeException,该索引不存在于数组中。但是在[arr removeLastObject]中,我猜iOS在数组为空时会自动检查忽略大小写