web-dev-qa-db-ja.com

NSUIntegerを保持するためにコアデータのどのNSNumber(整数16、32、64)を使用する必要がありますか

NSUIntegerをコアデータに保持したいのですが、必要なスペースに合わせてどのタイプ(整数16、32、64)を使用すべきかわかりません。

私の理解から:

Integer 16 can have minimum value of -32,768 to 32,767
Integer 32 can have minimum value of -2,147,483,648 to 2,147,483,647
Integer 64 can have minimum value of -very large to very large

nSUIntegerはunsigned longのtype defであり、unsigned intに等しくなります( iPhoneのObjective-Cのタイプ

nSUIntegerをnumberWithUnsignedInteger:でNSNumberに変換し、NSNumber(Integer 32)として保存すると、データを安全に取得できますか?

66
sarunw

本当にNSUIntegerの範囲全体が必要ですか? iOSでは、これは符号なし32ビット値であり、非常に大きくなる可能性があります。署名された64ビットを見つけます。

しかし、とにかくそれほど多くの精度は必要ないでしょう。 uint32_tの最大値はUINT32_MAXで、4,294,967,295(40億)です。 1秒に1回インクリメントすると、その値に達するまでに136年以上かかります。あなたのユーザーのiPhoneはその時までにはありません... :)

13
Daniel Eggert

可能な場合は、ディスクまたはネットワークを介してデータを書き込むときに、値のサイズを明示することが最善です。データ型としてNSUIntegerを使用する代わりに、必要な範囲に応じてuint16_tuint32_t、またはuint64_tを使用します。これは、コアデータの整数16、32、および64に自然に変換されます。

理由を理解するには、次のシナリオを検討してください。

  1. 整数64型を使用して値を保存することを選択します。
  2. 64ビットiOSデバイス(iPhone 6など)では、5,000,000,000の値が保存されます。
  3. 32ビットiOSデバイスでは、この値はストアからNSUIntegerにフェッチされます(NSNumberのunsignedIntegerValueを使用)。

NSUIntegerは32ビットデバイスでは32ビットのみであるため、50億を表すのに十分なビットがないため、数値は5,000,000,000ではなくなりました。ステップ3でuint64_tNUIntegerを交換した場合、値は50億のままです。

NSUIntegerを絶対に使用する必要がある場合は、上記の問題とそれを防御するためのコードに注意する必要があります。

署名されていない値を一見署名されたコアデータ型に格納する限り、安全に格納および取得できます。

NSManagedObject *object = // create object
object.valueNumber = @(4000000000); // Store 4 billion in an Integer 32 Core Data type
[managedObjectContext save:NULL] // Save value to store

// Later on
NSManagedObject *object = // fetch object from store
uint32_t value = object.valueNumber.unsignedIntegerValue; // value will be 4 billion
8
ospr