19

NSIndexPathのrowプロパティが符号付き整数であるのはなぜですか?

「有効な」負の値を取ることはできますか?

ここに画像の説明を入力してください

編集

符号比較をチェックするようにLLVMを設定した今日まで、これについては考えていませんでした。indexPath.row <= [someArray count]これにより、コンパイラは、または同様のものが存在する場合は常に警告を吐き出しました。

4

3 に答える 3

13

負の数を使用するとどうなりますか?

負の値を使用するのは賢明ではありません。使用すると、クレイジーな結果が得られます。

NSIndexPath* path = [NSIndexPath indexPathForRow:-2 inSection:0];

上記の結果、セクションは0になり、行は4294967294になります(これはNSUInteger私にはアンダーフローのように見えます!)これはUIKit Additionsカテゴリ内でのみ発生し、NSIndexPath自体では発生しないことを知っておいてください。の背後にある概念を見ると、NSIndexPath負の値を保持することは実際には意味がありません。なぜ?

(可能性あり)そうなる理由

NSIndexPathOS XのコアオブジェクトはNSUIntegerインデックスにsを使用しますが、UIKitAdditionはを使用しNSIntegerます。このカテゴリはコアオブジェクトの上にのみ構築されますが、NSIntegeroverを使用NSUIntegerしても追加の機能は提供されません。

なぜこのように機能するのか、私にはわかりません。私の推測(そして私は推測を規定している)は、iOSを最初に起動したときの素朴なAPIスリップアップだったということです。UITableViewiOS 2でリリースされたときはNSInteger、さまざまな目的でsを使用していました(などnumberOfSections)。考えてみてください。これは概念的には意味がありません。負の数のセクションを持つことはできません。現在、iOS 6でも、それはまだを使用してNSIntegerいるので、テーブルビューとの以前のアプリケーションの互換性を壊さないでください。

に加えUITableViewNSIndexPath、への追加があります。これは、テーブルビューと組み合わせて、その行などにアクセスするために使用されます。それらは連携する必要があるため、互換性のあるタイプ(この場合NSInteger)が必要です。

タイプをNSUInteger全面的に変更すると、多くの問題が発生します。安全なAPI設計を行うには、NSIntegerとNSUIntegerの対応するものが安全に並行して動作できるように、すべての名前を変更する必要があります。Appleはおそらくこの面倒なことを望んでおらず(そして開発者もそうは思わない!)、そのため彼らはそれを維持しているNSInteger

于 2012-11-27T14:15:14.657 に答える
2

考えられる理由の1つは、符号なしタイプが非常に簡単にアンダーフローすることです。例として、NSUIntegerコードにストローク幅の変数がありました。このストロークでペイントされたポイントの周りに「エンベロープ」を作成する必要があったため、次のコードを使用します。

NSUInteger width = 3;
CGRect envelope = CGRectInset(CGRectZero, -width, -width);
NSLog(@"%@", NSStringFromCGRect(envelope));

符号なしの型では、これはを出力{{inf, inf}, {0, 0}}し、符号付きの整数では、を取得します{{-3, -3}, {6, 6}}。その理由は、width変数の前の単項マイナスがアンダーフローを作成するためです。これは誰かには明らかかもしれませんが、多くのプログラマーを驚かせるでしょう:

NSUInteger a = -1;
NSUInteger b =  1;
NSLog(@"a: %u, b: %u", a, -b); // a: 4294967295, b: 4294967295

したがって、負の値を使用することが意味をなさない(ストローク幅を負にすることはできない)状況でも、負のコンテキストで値を使用することは意味があり、アンダーフローが発生します。署名付きタイプに切り替えると、範囲を適度に高く保ちながら、驚きが少なくなります。いい妥協のように聞こえます。

于 2012-11-27T14:50:53.920 に答える
0

NSIndexPath意図的に使用NSIntegerタイプのUIKit追加だと思います。何らかの理由parameterで任意のメソッドに関して負の行が渡された場合(現時点では何も表示されませんが...)、NSIntegerMax + parameter値への自動キャストは行われず、存在する可能性のあるオブジェクトは存在しない途方もなく大きなパラメーターを検索しません。それでも、これを防ぐ方法は他にもあるので、好みの問題かもしれません。

たとえば、私はクラスのNSUIntegerパラメーターとしてではなく、符号をチェックし、パラメーターが負の場合はまったく作成しませんでした。NSIndexPathNSIntegerNSIndexPath

于 2014-03-14T10:30:28.017 に答える