2012-01-13 1 views
59

Я хочу сохранить NSUInteger в свои основные данные, и я не знаю, какой тип я должен использовать (целое число 16, 32, 64) чтобы удовлетворить требуемое пространство.Что NSNumber (Integer 16, 32, 64) в основных данных следует использовать для хранения NSUInteger

Из моего понимания

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 является тип Защиту от unsiged длиной, которая равна неподписанных Int (Types in objective-c on iPhone)

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

ответ

15

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

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

+24

Это не реально ответить на этот вопрос. Откуда вы знаете, какие данные он хранит? У меня было много случаев, когда мне нужно было хранить номер намного больше, чем 4 миллиарда. – Brandon

+0

Например: 'вар str2 =«небольшая строка с большим значением хэш»' ' печать (str2.hashValue)' ' // 4799450061348893706' –

+0

бесполезен - возможно, он использует Int как способ сохранения состояния на 32 отдельный атрибут - 32 человека перевернут все биты и сделают беспорядок вещей – SimonTheDiver

6

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

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

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

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

Если вам абсолютно необходимо использовать NSUInteger, вам просто нужно быть осторожным в отношении описанных выше проблем и защищать код для него.

Что касается хранения значений без знака в, казалось бы, подписанными типы Core Data, вы можете безопасно хранить их и получить их:

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