核心数据中的 NSNumber (Integer 16,32,64)用于保存 NSUInteger

我想保持 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 的类型 def 是无符号 long,等于无符号 int (IPhone 上 Objective-c 中的类型)

所以如果我用 numberWithUnsignedInteger 将我的 NSUInteger 转换成 NSNumber: 并将其保存为 NSNumber (Integer 32) ,我就可以安全地检索回我的数据,对吗?

41141 次浏览

你需要 真的的整个范围的 NSUInteger?在 iOS 上,这是一个无符号的32位值,它可以变得非常大。它会找到一个签名的64位。

但你可能不需要那么精确。uint32_t的最大值是 UINT32_MAX,即4,294,967,295(40亿)。如果你每秒钟增加一次,你将需要超过136年才能达到这个值。到那时,用户的 iPhone 将不复存在... :)

如果可能的话,在将数据写入磁盘或通过网络时,最好明确说明值的大小。不要使用 NSUInteger 作为数据类型,而是根据需要的范围使用 uint16_tuint32_tuint64_t。然后在核心数据中自然转换为整数16、32和64。

为了理解其中的原因,考虑一下这个场景:

  1. 您选择使用 Integer 64类型来存储您的值。
  2. 在64位的 iOS 设备(如 iPhone6)上,它存储了5,000,000,000的值。
  3. 在32位 iOS 设备上,这个值从存储获取到 NSUInteger(使用 NSNumber 的 unsignedIntegerValue)。

现在,因为 NSUInteger在32位设备上只有32位,所以这个数字不再是50亿,因为没有足够的比特来表示50亿。如果您将步骤3中的 NUInteger交换为 uint64_t,那么价值仍然是50亿。

如果您绝对必须使用 NSUInteger,那么您只需要对上面描述的问题保持警惕,并为其编写防御性代码。

As far as storing unsigned values into the seemingly signed Core Data types, you can safely store them and retrieve them:

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