上記のコメントで @ale0xB が診断したように、実際にはメソッドNSNumber の独自の実装を提供していません。-initWithBytes:objCType:したがって、そのセレクターを呼び出すと、実際にはNSNumberの基本クラスからの実装が取得されNSValueます。と の間には1つの違いは[[NSNumber alloc] initWithBytes:foo objCType:bar]ありません[[NSValue alloc] initWithBytes:foo objCType:bar]— どちらも同じメソッドの実装を呼び出します。これは、指定された を解放し、一般にタイプ( の文書化されていないサブクラスであり、 ではありません)selfである新しいオブジェクトを返します。NSConcreteValueNSValueNSNumber
さらに明確にするために:
#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 – そのコードには、特に後のリビジョンで、いくつかのバグがあります。私のパッチはこちらを参照してください。)