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] 発生 (null)。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 がスローされます。しかし、[arr removeLastObject] では、配列が空の場合、iOS は大文字と小文字を区別しないように自動的にチェックしていると思います。

于 2013-02-07T20:44:37.787 に答える