2016-11-09 7 views
4

ダイナミックリンクを使用するメソッドに、符号なし整数として16進値を渡そうとしています。私がパラメータとして渡す値は、何らかの形で壊れています。何が起こっている?performSelectorに符号なしintを渡すことでビットが失われるのはなぜですか?

- (void)callPerformSelector 
{ 
    NSNumber *argument = [NSNumber numberWithUnsignedInt:(unsigned int)0xFFFFFFFF]; 
    SEL selector = NSSelectorFromString(@"testPerformSelector:"); 
    NSLog(@"testPerformSelector object %@", argument); 
    [self performSelector:selector withObject:argument]; 
} 

- (void)testPerformSelector:(unsigned int) arg1 
{ 
    NSLog(@"testPerformSelector unsigned int %u", arg1); 
    NSLog(@"testPerformSelector hex %X", arg1); 
} 

出力は次のとおりです。

testPerformSelector object 4294967295 
testPerformSelector unsigned int 4294967283 
testPerformSelector hex FFFFFFF3 

答えて

1

あなたが唯一のセレクタではなくプリミティブ型にオブジェクトを渡すことができますので、セレクタは次のようになります。

- (void)testPerformSelector:(NSNumber *) arg1 
{ 
    NSLog(@"testPerformSelector hex %x", [arg1 unsignedIntValue]); 
} 

更新:指摘アウトしたようで@ gnasher729の場合、数字が-13のように見えるのは、それがtagged pointerだからです。

+0

タグ付きポインタです。あなたが見ているのは、数字の下位24ビット、続いて8ビットのタグです。 – gnasher729

+0

@ gnasher729ありがとうございました。更新された答え。 – Droppy

4

それはする必要がありますので:

- (void)callPerformSelector 
{ 
    NSNumber *argument = @0xFFFFFFFF; 
    SEL selector = @selector(testPerformSelector:); 
    NSLog(@"testPerformSelector object %@", argument); 
    [self performSelector:selector withObject:argument]; 
} 

- (void)testPerformSelector:(NSNumber *) arg1 
{ 
    NSLog(@"testPerformSelector unsigned int %u", arg1.unsignedIntValue); 
} 

unsigned intNSNumber *が容易な理由と複雑な理由があります別物

2

です。

単純な理由:なぜこれが機能しないのですかperformSelectorWithObjectのターゲットへの最初の引数はオブジェクトでなければなりません。関数シグネチャの符号なし整数へのポインタを指定していますが、呼び出すときにオブジェクト(NSNumber)を渡しています。だから、代わりに:

- (void)testPerformSelector:(unsigned int) arg1 

あなたは、オブジェクトの外に0xFFFFFFFFを取得するためにNSNumberunsignedIntValueを使用する必要があります

- (void)testPerformSelector:(NSNumber *) arg1 

を持つ必要があります。

複雑な理由ははるかに面白いです:なぜこれはほとんど動作し、それがいくつかのビットを失うように見えます。 NSNumberは数値をラップするオブジェクトで、これは生の数値とは大きく異なります。しかし、NSNumberはタグ付けされたポインタとして実装されているので、オブジェクト-cはオブジェクトであると認識してオブジェクトのように扱いますが、NSNumber値のサブセットはタグ付きポインタとして実装され、実際の値は "ポインタ"ポインタの下位4ビット(それ以外の場合は常に0)に表示されます。see Friday Q&A

関連する問題