В Какао вы предпочитаете NSInteger или int, и почему?
NSInteger
/ NSUInteger
- это определенные какао замены для обычных встроенных типов.
Есть ли преимущества в использовании типов NS * по сравнению со встроенными? Что вы предпочитаете и почему? Имеют ли NSInteger
и int
одинаковую ширину на 32-битных / 64-битных платформах?
Ответов (5)5
Насколько я понимаю, NSInteger et al. являются архитектурно безопасными версиями соответствующих типов C. В основном их размер зависит от архитектуры, но NSInteger, например, гарантированно хранит любой действительный указатель для текущей архитектуры.
Apple рекомендует использовать их для работы с OS X 10.5 и новее, а API Apple: s будет их использовать, так что определенно неплохо выработать привычку их использовать. Они требуют немного большего набора текста, но кроме этого, похоже, нет никаких причин не использовать их.
64-битность - это, собственно, смысл существования NSInteger и NSUInteger; до 10.5 их не было. Два просто определены как long в 64-битной версии и как int в 32-битной:
#if __LP64__ || NS_BUILD_32_LIKE_64
typedef long NSInteger;
typedef unsigned long NSUInteger;
#else
typedef int NSInteger;
typedef unsigned int NSUInteger;
#endif
Таким образом, используя их вместо более базовых типов C, когда вам нужен «битовый» размер.
Проблемы квантования для 64-битной среды выполнения
В некоторых ситуациях может быть веская причина использовать стандартные типы вместо NSInteger
: «неожиданного» увеличения памяти в 64-битной системе.
Очевидно, что если целое число равно 8, а не 4 байтам, объем памяти, занимаемой значениями, удваивается. Однако, учитывая, что не каждое значение является целым числом, обычно не следует ожидать, что объем памяти, занимаемый вашим приложением, увеличится вдвое. Однако способ выделения памяти в Mac OS X меняется в зависимости от запрошенного объема памяти.
В настоящее время, если вы запрашиваете 512 байт или меньше, malloc
выполняется округление до следующего числа, кратного 16 байтам. Однако, если вы запрашиваете более 512 байт, malloc
округляется до следующего числа, кратного 512 (не менее 1024 байтов). Предположим, что вы определяете класс, который, среди прочего, объявляет пять NSInteger
переменных экземпляра, и что в 32-битной системе каждый экземпляр занимает, скажем, 272 байта. В 64-битной системе экземплярам теоретически потребуется 544 байта. Но из-за стратегии распределения памяти каждый фактически занимает 1024 байта (почти в четыре раза больше). Если вы используете большое количество этих объектов, объем памяти вашего приложения может быть значительно больше, чем вы могли ожидать. Если вы замените NSInteger
переменные на sint_32
переменные, вы будете использовать только 512 байт.
Поэтому, когда вы выбираете, какой скаляр использовать, убедитесь, что вы выбрали что-то разумное. Есть ли причина, по которой вам нужно значение больше, чем нужно в вашем 32-битном приложении? Использование 64-битного целого числа для подсчета секунд вряд ли понадобится ...