Какой NSNumber (целое число 16, 32, 64) в Core Data я должен использовать, чтобы сохранить NSUInteger - PullRequest
66 голосов
/ 13 января 2012

Я хочу сохранить 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, которое равно unsigned int ( Типы в target-c на iPhone )

итак, если я преобразую свой NSUInteger в NSNumber с помощью numberWithUnsignedInteger: и сохраню его как NSNumber (целое число 32), я мог бы безопасно вернуть свои данные обратно, верно?

Ответы [ 2 ]

13 голосов
/ 14 января 2012

Вам действительно нужен весь диапазон NSUInteger?На iOS это 32-разрядное значение без знака, которое может быть очень большим.Он найдет 64-битную подпись.

Но вам, вероятно, не нужна такая большая точность в любом случае.Максимальное значение для uint32_t составляет UINT32_MAX, что составляет 4 294 967 295 (4 миллиарда).Если вы увеличиваете значение раз в секунду, вам понадобится более 136 лет, чтобы достичь этого значения.IPhone вашего пользователя к тому времени уже не будет ...:)

8 голосов
/ 28 ноября 2014

Если это вообще возможно, при записи данных на диск или по сети лучше четко указывать размер значения.Вместо использования NSUInteger в качестве типа данных используйте uint16_t, uint32_t или uint64_t в зависимости от необходимого диапазона.Затем это естественным образом переводится в целочисленные значения 16, 32 и 64 в базовых данных.

Чтобы понять, почему, рассмотрим следующий сценарий:

  1. Вы решили использовать тип Integer 64 для хранения своего значения.
  2. На 64-разрядном устройстве iOS (например,iPhone 6) он хранит значение 5 000 000 000.
  3. На 32-разрядном устройстве iOS это значение выбирается из хранилища в NSUInteger (с использованием NSNumber's unsignedIntegerValue).

Теперь, поскольку NSUInteger является 32-разрядным на 32-разрядном устройстве, число больше не составляет 5 000 000 000, потому что недостаточно битов для представления 5 миллиардов.Если вы поменяли NUInteger в шаге 3 на uint64_t, тогда значение все равно будет равно 5 млрд.

Если вам абсолютно необходимо использовать 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
...