5

根据NSMutableArray 文档

removeLastObjectNSRangeException如果数组中没有对象,则引发一个。

出于某种原因,我似乎可以在一个空数组上调用此方法,并且没有抛出异常。

这是一个测试用例:

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

这个测试用例在最后一行对我来说失败了,消息是:

[arr removeLastObject] 提出(空)。应该抛出 NSRangeException

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

4

2 回答 2

5

查看程序集,Lion 中的这种行为似乎发生了变化。这是实现的一部分[__NSArrayM removeLastObject](这是您正在调用的实际实现):

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

这调用CFExecutableLinkedOnOrAfter值为 7;如果返回 1 (它在我的机器上),你就会得到你所看到的行为。如果它返回 0,你会得到一个异常。

CFExecutableLinkedOnOrAfter是一个未记录的函数,但一些窥探表明如果可执行文件在特定版本的 Mac OS X 之后链接,它会返回。更多的窥探表明 7 的值对应于 10.7。

因此,如果您正在运行 Lion 或更高版本,则不会出现异常。对我来说听起来像是一个文档错误!

于 2013-02-07T21:03:12.743 回答
1

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

于 2013-02-07T20:44:37.787 回答