2012-04-22 2 views
3

Не знаете, почему Objective-C решил использовать NSNumber вместо float, double и т. Д. Как этот тип представлен на диске?Как NSNumber представлен на диске?

+0

Что такое * диск * имеет к этому отношение?Вы имели в виду «как это представлено в памяти»? .. – dasblinkenlight

ответ

7

NSNumber является toll-free bridged с CFNumber. В последних реализациях Core Foundation CFNumber является указателем с тегами. Это позволяет рассматривать его как объект, но без всех накладных расходов на объект. Вместо этого значение кодируется в указателе объекта (и на самом деле это не указатель).

См. Tagged pointers and fast-pathed CFNumber integers in Lion.

+0

+1: Но он сохраняется только как тегированный указатель, если Number является целым числом, и значение будет соответствовать доступной памяти. В противном случае это полный объект (со всеми связанными служебными данными). – lnafziger

4

NSNumber является потомком NSObject, так что он может пойти везде, где id может пойти: NSarray, NSDictionary, и так далее. Примитивы, такие как int и double не могут пойти в эти классы, потому что они не наследуют от NSObject, и, следовательно, не могут участвовать в собраниях и т.д.

Если бы я был догадаться, на внутренностях NSNumber. Я бы сказал, что это объединение и поле выбора типа. Тем не менее, красота инкапсуляции позволяет мне успешно программировать до NSNumber, не зная в первую очередь о его представлении (и не пропуская это знание).

+0

Надеюсь, я правильно прочитал ваш разум в первом предложении. Предполагая, что он похож на 'CFNumber', [реализация] (http://opensource.apple.com/source/CF/CF-635.19/CFNumber.c) довольно сложнее, чем объединение, возможно, для сохранения нескольких байтов для меньших типов. – ughoavgfhw

+0

@ughoavgfhw Спасибо за редактирование - действительно, вы правильно прочитали мой разум на 100%. Спасибо за упоминание «CFNumber»: я знаю только самые основы «CF», в основном для того, чтобы обойтись в ситуациях, когда нет «мостового» класса. Я очень рад, что эти знания не являются (или, по крайней мере, не более) основным требованием для создания рабочих приложений. Еще раз, спасибо! – dasblinkenlight

1

Одна вещь, чтобы иметь в виду, что Objective-C является супер-набор C, поэтому они не решили использовать NSNumberвместо примитивных типов (поплавка, двойной и т.д.), но в дополнение к ним. Если вам не нужны функции NSNumber, просто используйте примитивные типы и сохраните накладные расходы на создание/уничтожение объектов. Многие функции в iOS (особенно функции типа массива) только Работает с объектами (потомки NSObject). Поэтому, если вы хотите передать некоторый тип номера в одну из этих функций, вам потребуется представление объекта. Это где NSNumber приходит в

Процитируют документацию на NSNumber:.

NSNumber подкласс NSValue, который предлагает значение, как любой C скаляр (числовые) типа. Он определяет набор методов, специально предназначенных для установки и доступа к значению в виде подписанного или unsigned char, short int, int, long int, long long int, float или double или как BOOL. (Обратите внимание, что числовые объекты не обязательно сохраняют тип, который они создаются с.) Он также определяет метод compare: для определения порядка двух объектов NSNumber.

Обратите внимание, что внутренне фактическое значение хранится либо в виде целого числа или в виде числа с плавающей точкой (в пределах либо меченого указателя, как описывает Джей или объединение в объекте), в зависимости от того, какое значение вы хранения. Это важно знать, как если бы вы попытались сохранить номер типа «32.1», он сохранит его как число с плавающей запятой, и когда вы его извлечете, скорее всего, получите что-то вроде «32.09999999999999».

Что касается хранения его на диск, если вам нужно сделать это, то вы обычно храните его с encodeWithCoder и получить его с помощью initWithEncoder, который преобразует его в формат, предназначенный для сохранения на диск, а затем прочитать обратно.