IOS用に開発するとき、NSInteger
とintの組み合わせはいつ使うべきですか? Appleのサンプルコードでは、関数への引数として値を渡すとき、または関数から値を返すときにNSInteger
(またはNSUInteger
)を使用しています。
- (NSInteger)someFunc;...
- (void)someFuncWithInt:(NSInteger)value;...
しかし関数内では、値を追跡するためにint
を使用しているだけです。
for (int i; i < something; i++)
...
int something;
something += somethingElseThatsAnInt;
...
私はNSInteger
が64ビットまたは32ビット環境で整数を参照するための安全な方法であると読んだ(言われました)それではなぜint
を使用するのですか?
あなたのコードがどのようなプロセッサアーキテクチャで動作するのかわからないときは通常NSInteger
を使いたいでしょう。そのため何らかの理由で最大のint
型を使いたいかもしれません。 64ビットシステムではint
ですが、long
だけです。
特に必要でない限り、NSInteger
/int
の代わりにlong
を使用します。
NSInteger
/NSUInteger
は、これらの型の1つに対して* dynamic typedef
*として定義され、次のように定義されます。
#if __LP64__ || TARGET_OS_EMBEDDED || TARGET_OS_IPHONE || TARGET_OS_WIN32 || NS_BUILD_32_LIKE_64
typedef long NSInteger;
typedef unsigned long NSUInteger;
#else
typedef int NSInteger;
typedef unsigned int NSUInteger;
#endif
これらの各型に使用する正しい形式指定子については、 『String Programming Guide』のプラットフォーム依存関係に関するセクション を参照してください。
なぜint
を使うのですか?
ループ制御変数(ループの繰り返しを制御するためにのみ使用される)にはint
を使用します。int
データ型は、データ型サイズとループに保持できる値の両方で問題ありません。 ここではプラットフォームに依存するデータ型は必要ありません。ループ制御変数の場合、16ビットのint
でさえもほとんどの場合に役立ちます。
Appleは、関数の戻り値や関数の引数にNSInteger
を使用しますこの場合、データ型[size]が重要です、関数を使っているのは他のプログラムや他の部分とのデータのやり取りです。コードのへの答えを参照してください。あなた自身の質問で、私はいつNSInteger vs intを使用すべきですか?.
それらは、関数への引数として値を渡すか、またはを返すときにNSInteger(またはNSUInteger)を使用します。関数からの値。
OS Xは "LP64"です。この意味は:
int
name__は常に32ビットです。
long long
は常に64ビットです。
NSInteger
name__とlong
name__は常にポインタサイズです。つまり、32ビットシステムでは32ビット、64ビットシステムでは64ビットです。
NSIntegerが存在する理由は、多くの従来のAPIがポインタサイズの変数を保持するためにint
name__ではなくlong
name__を誤って使用していたためです。つまり、APIは64ビットバージョンでint
name__からlong
name__に変更する必要がありました。言い換えれば、32ビットと64ビットのどちらのアーキテクチャ用にコンパイルしているかに応じて、APIには異なる関数シグネチャがあります。 NSInteger
name__は、これらの従来のAPIでこの問題を隠そうとしています。
新しいコードで、32ビット変数が必要な場合はint
name__を、64ビット整数が必要な場合はlong long
を、ポインターサイズの変数が必要な場合はlong
name__またはNSInteger
name__を使用します。
NSIntegerの実装を詳しく調べると、
#if __LP64__
typedef long NSInteger;
#else
typedef int NSInteger;
#endif
単純に、NSInteger typedefはあなたのためにステップを実行します:アーキテクチャが32ビットであればint
を使い、64ビットであればlong
を使います。 NSIntegerを使用すれば、プログラムが実行されているアーキテクチャについて心配する必要はありません。
NSNotFoundやNSIntegerMaxなどの定数値と比較する必要がある場合はNSIntegersを使用する必要があります。これらの値は32ビットシステムと64ビットシステムでは異なるため、インデックス値、カウントなどはNSIntegerまたはNSUIntegerを使用します。
NSIntegerを2倍のメモリを消費することを除いて、ほとんどの状況で使用しても問題ありません。メモリへの影響は非常に小さいですが、一度に膨大な数の浮動小数点数がある場合は、intを使用すると効果があります。
NSIntegerまたはNSUIntegerを使用する場合は、フォーマット文字列を使用するときにそれらを長整数または符号なし長整数にキャストすることをお勧めします。NSIntegerを既知の長さと同じようにログアウトしようとすると新しいXcode機能が警告を返すためです。整数として型指定されている変数または引数にそれらを送信するときは、同様に慎重になる必要があります。これは、プロセスである程度の精度が失われる可能性があるためです。
概して、一度に何十万ものメモリをメモリに保持することを期待していないのであれば、NSIntegerを使用する方が両者の違いを常に心配するよりも簡単です。
IOSでは、現在int
name__とNSInteger
name__のどちらを使用してもかまいません。 iOSが64ビットに移行したときにはもっと重要になります。
簡単に言うと、NSInteger
name__sは32ビットコードではint
name__s(したがって32ビット長)であり、64ビットコードではlong
name__s(64ビットコードではlong
name__sは64ビット幅ですが、32ビットコードでは32ビット)です。 NSInteger
name__の代わりにlong
name__を使用する最も可能性の高い理由は、既存の32ビットコード(int
name__sを使用)を壊さないことです。
CGFloat
name__にも同じ問題があります。32ビット(少なくともOS X)では、float
name__です。 64ビットではdouble
name__です。
更新: iPhone 5s、iPad Air、Retina搭載iPad Mini、およびiOS 7の導入により、iOS上で64ビットコードを構築できるようになりました。
pdate 2 :また、NSInteger
name__sを使用すると、Swiftコードの相互運用性が向上します。
現在(2014年9月)現在、arm 64用のアプリも作成している場合は、iOS APIなどと対話するときにNSInteger/CGFloat
を使用することをお勧めします。これは、float
、long
、およびint
型を使用すると予期しない結果が生じる可能性があるためです。
例:FLOAT/DOUBLEとCGFLOAT
例として、UITableViewデリゲートメソッドtableView:heightForRowAtIndexPath:
を取ります。
32ビットのみのアプリケーションでは、このように書かれていればうまく動作します。
-(float)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 44;
}
float
は32ビット値で、返される44は32ビット値です。ただし、これと同じコードを64ビットのarm64アーキテクチャでコンパイルまたは実行すると、44は64ビットの値になります。 32ビット値が予想されるときに64ビット値を返すと、予期しない行の高さが発生します。
この問題を解決するには、CGFloat
型を使用します。
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 44;
}
この型は、32ビット環境では32ビットfloat
を、64ビット環境では64ビットdouble
を表します。したがって、この型を使用すると、コンパイル/ランタイム環境に関係なく、メソッドは常に期待される型を受け取ります。
整数を期待するメソッドにも同じことが言えます。このようなメソッドは、32ビット環境では32ビットint
値、64ビット環境では64ビットlong
値を想定します。この問題を解決するには、コンパイル/ランタイム環境に基づいてNSInteger
またはint
として機能するlong
型を使用します。
int = 4バイト(アーキテクトのサイズに関係なく固定)NSInteger =アーキテクトのサイズに依存(例:4バイトのアーキテクト= 4バイトのNSIntegerのサイズ)