1

字幕:なぜこのコードが機能するのですか?ある種の強制によってタイプNSNumberとの比較が可能になるようです。からの選択を以前に保存された値とNSString比較しようとしています。UISegmentedControl

- (IBAction)minSegmentedControlChanged:(id)sender // MINIMUM value
{
UISegmentedControl *s1 = (UISegmentedControl *)sender;

NSMutableArray *pD = [[GameData gameData].curData valueForKey:@"persData"];

// Must make sure max >= min

NSNumber *currMax = [pD objectAtIndex:1];
NSLog(@"%@", [currMax class]); // __NSCFString ?!

int ss1 = s1.selectedSegmentIndex;
NSNumber *SS1 = [NSNumber numberWithInt:ss1 + 2];

if (SS1 >= currMax) SS1 = currMax;

NSLog(@"%@", SS1); // Answer is correct, appears to be an integer
NSLog(@"%@", [SS1 class]); // __NSCFString ?!

[pD replaceObjectAtIndex:0
              withObject:SS1];
[[GameData gameData].curData setObject:pD
                                forKey:@"persData"];
NSLog(@"%@", [[GameData gameData].curData valueForKey:@"persData"]);

}

私は特に質問しています:

NSNumber *currMax = [pD objectAtIndex:1];
NSLog(@"%@", [currMax class]); // __NSCFString ?!

これは、数値の文字列を返すようです。 [[GameData gameData].curData valueForKey:@"persData"];次のように初期化されます。

         _persData = [[NSMutableArray alloc] initWithObjects:@"2", @"8", @"TWL", @"0", @"0", nil];

これは要素1の文字列です。では、なぜそれを要求できるのでしょうか。NSNumberこれは、実際に__NSCFString算術比較を実行できる上にあることを報告します。私はObjective-Cに数か月しかいませんが、これは奇妙に思えます。

4

2 に答える 2

8

さて、これを一度に1ステップずつ見ていきましょう。

まず第一に、のすべての要素_persDataは文字列です。限目。NSStringはクラスクラスタであるため、問い合わせるさまざまなインスタンスの具体的なクラスは奇妙に見えるかもしれませんが、これは、この説明に関係のないフリーダイヤルのブリッジングやその他の魔法をサポートするためのものです。

NSNumber *currMax = [pD objectAtIndex:1];

この行は正しくありません。ある種の強制が行われていると思うかもしれませんが、実際には、にを割り当てているだけNSString *ですNSNumber *。これは間違っており、できるだけ早くあなたの顔に爆発します。objectAtIndex:型情報が削除されたが返されることがあるidので、コンパイラはそれを正しい種類のポインタに格納することを信頼していますが、メッセージを送信しようとするまで強制されません。

if (SS1 >= currMax) SS1 = currMax;

これは非常に賢明な比較です。SS1は間違いNSNumberなくcurrMaxですが、NSStringです。ただし、これらのオブジェクトの値を比較しているわけではありません。そのためには、このメソッドを使用しcompare:ます。代わりに、メモリ内のアドレスのみを見て、それらをポインタとして比較しています。実装の偶然により、SS1常により高いアドレスに存在するようですcurrMax

上記のすべてが当てはまる場合、上記の行が実行された後SS1は常にタイプNSStringになります。これが、この行の理由を説明しています。

NSLog(@"%@", [SS1 class]);

常にそれSS1が文字列であることを示します。

于 2012-06-26T01:43:40.727 に答える
2

実際には、数値ではなく、で初期化しNSMutableArrayますNSString

を使用してオブジェクトをプルアウトするNSMutableArrayobjectAtIndex、関数の戻りタイプは、になります。これは、実際のオブジェクトが。であるのに対し、id盲目的ににキャストされます。NSNumberNSString

SS1 >= currMaxステートメントは、オブジェクトの値ではなく、オブジェクトのアドレスを比較しているようです。

このコードスニペットでテストできます。

NSNumber *a = [[NSNumber alloc] initWithUnsignedInt: 34];
NSNumber *b = [[NSNumber alloc] initWithUnsignedInt: 3];

NSNumber *c = [[NSNumber alloc] initWithUnsignedInt: 34];
NSNumber *d = [[NSNumber alloc] initWithUnsignedInt: 234];

NSLog(@"%p %p %p %p %d %d", a, b, c, d, a >= b, c >= d);
于 2012-06-26T01:34:57.580 に答える