上記のコメントで @ale0xB が診断したように、実際にはメソッドNSNumber
の独自の実装を提供していません。-initWithBytes:objCType:
したがって、そのセレクターを呼び出すと、実際にはNSNumber
の基本クラスからの実装が取得されNSValue
ます。と の間には1つの違いは[[NSNumber alloc] initWithBytes:foo objCType:bar]
ありません[[NSValue alloc] initWithBytes:foo objCType:bar]
— どちらも同じメソッドの実装を呼び出します。これは、指定された を解放し、一般にタイプ( の文書化されていないサブクラスであり、 ではありません)self
である新しいオブジェクトを返します。NSConcreteValue
NSValue
NSNumber
さらに明確にするために:
#import <assert.h>
#import <Foundation/Foundation.h>
int main()
{
id x;
x = [NSNumber numberWithInt:42];
assert( [x isKindOfClass:[NSNumber class]] );
assert( [x respondsToSelector:@selector(intValue)] );
int fortytwo = 42;
x = [[NSNumber alloc] initWithBytes:&fortytwo objCType:@encode(int)];
assert( [x isKindOfClass:[NSValue class]] );
assert( ! [x isKindOfClass:[NSNumber class]] ); // yikes!
assert( ! [x respondsToSelector:@selector(intValue)] ); // your particular problem
}
ただし、カテゴリは救助に!Martin Häcker は、NSNumber(CreatingFromArbitraryTypes)
あなたがやりたいことに適応できるカテゴリーを書きました。パブリック ドメインのソース コードはこちらからご覧ください。2基本的な考え方は、考えられるすべての型エンコーディングを特殊なケースにすることです。
- をエンコードしようとしている場合は
"i"
、にディスパッチし-numberWithInt:
ます。
- をエンコードしようとしている場合は
"f"
、にディスパッチし-numberWithFloat:
ます。
等々。これは面倒です。しかし、一度コードを書いたら、それ以降はカテゴリを使用して、単純に を呼び出すことができます[NSNumber numberWithValue:myNSValue]
。
( 1 – 多かれ少なかれ。この文脈では大きな違いはありません。)
( 2 – そのコードには、特に後のリビジョンで、いくつかのバグがあります。私のパッチはこちらを参照してください。)