Использование enum, uint32_t и сдвига битов в константах Objective C UIFontDescriptor.h
Я знакомлюсь с целью C и немного понимаю типы enum.
Вот пример кода, который можно увидеть здесь и который я буду использовать в следующем уроке:
UIFont *bodyFont = [UIFont preferredFontForTextStyle:UIFontTextStyleBody];
UIFontDescriptor *existingDescriptor = [bodyFont fontDescriptor];
UIFontDescriptorSymbolicTraits traits = existingDescriptor.symbolicTraits;
traits |= UIFontDescriptorTraitBold;
UIFontDescriptor *newDescriptor = [existingDescriptor fontDescriptorWithSymbolicTraits:traits];
UIFont *boldBodyFont = [UIFont fontWithFontDescriptor:newDescriptor size:0];
Из того, что я понимаю, bodyFont устанавливается с помощью метода класса UIFont, затем существующий Descriptor создается путем извлечения этого из bodyFont. Существующие UIFontDescriptorSymbolicTraits затем извлекаются из этого и сохраняются в чертах.
Я не понимаю, что следует после этого (traits |= UIFontDescriptorBold;) Из поиска в Google я понимаю, что это немного мудрое сравнение, а затем присваивание, но я не уверен, почему это должно быть сделано его способом. Переходя к моему следующему вопросу.
Из API для UIFontDescriptor.h ( https://developer.apple.com/library/ios/documentation/uikit/reference/UIFontDescriptor_Class/Reference/Reference.html)
typedef enum : uint32_t {
/* Typeface info (lower 16 bits of UIFontDescriptorSymbolicTraits) */
UIFontDescriptorTraitItalic = 1u << 0,
UIFontDescriptorTraitBold = 1u << 1,
UIFontDescriptorTraitExpanded = 1u << 5,
UIFontDescriptorTraitCondensed = 1u << 6,
UIFontDescriptorTraitMonoSpace = 1u << 10,
UIFontDescriptorTraitVertical = 1u << 11,
UIFontDescriptorTraitUIOptimized = 1u << 12,
UIFontDescriptorTraitTightLeading = 1u << 15,
UIFontDescriptorTraitLooseLeading = 1u << 16,
/* Font appearance info (upper 16 bits of UIFontDescriptorSymbolicTraits */
UIFontDescriptorClassMask = 0xF0000000,
UIFontDescriptorClassUnknown = 0u << 28,
UIFontDescriptorClassOldStyleSerifs = 1u << 28,
UIFontDescriptorClassTransitionalSerifs = 2u << 28,
UIFontDescriptorClassModernSerifs = 3u << 28,
UIFontDescriptorClassClarendonSerifs = 4u << 28,
UIFontDescriptorClassSlabSerifs = 5u << 28,
UIFontDescriptorClassFreeformSerifs = 7u << 28,
UIFontDescriptorClassSansSerif = 8u << 28,
UIFontDescriptorClassOrnamentals = 9u << 28,
UIFontDescriptorClassScripts = 10u << 28,
UIFontDescriptorClassSymbolic = 12u << 28
} UIFontDescriptorSymbolicTraits;
В чем смысл обозначения enum: uint32_t? Я знаю использование enum и знаю, что uint32_t означает 32-разрядное целое число без знака (хотя я не уверен, насколько оно отличается от обычного целого без знака).
Другой вопрос, почему значения создаются как сдвинутые биты, а не просто обычные целые числа? Почему некоторые значения пропускают биты или числа (например, UIDescriptorClassSlabSerifs идет от 5u << 28 до 7u << 28. Или UIFontDescriptorTraitBold 1u<<1 до 1u<<5)?
Пожалуйста, дайте мне знать, если мои вопросы требуют дальнейшего объяснения.
2 ответа
: uint32_t
определяет размер хранилища, которое используется для переменных этого типа. uint_32t
означает, что независимо от архитектуры у вас есть ровно 32 бита информации. Он не подписан, поскольку перестановка битов в целых числах со знаком может привести к неожиданным результатам.
Значения указываются таким образом, чтобы было ясно, что они используются как флаги для компоновки; значение, хранящееся в переменной этого типа, содержит много информации. Это намного легче читать и писать 1u << 5
1u << 6
чем переводить с десятичного в вашем мозгу. Пропущенные биты предназначены либо для расширения в будущем, либо для группировки связанных флагов, опять же для удобства чтения.
|=
Оператор не сравнение, это назначение. Это похоже на +=
, который добавляет правый операнд к левому и сохраняет результат в последнем. В этом случае он выполняет побитовое ИЛИ, которое устанавливает биты, указанные справа. Вот как вы добавляете флаги в битовую маску.
traits |= UIFontDescriptorBold
это не сравнение, просто бит или значение UIFontDescriptorBold
в стоимость traits
, Базовая "С".
enum : uint32_t
расширение Apple, которое приводит к тому, что перечисление использует 32-разрядные значения без знака uint32_t
,
1u << 5
и тому подобное используются для создания битовых значений с одним установленным битом. Это позволяет использовать различные параметры в комбинации для указания набора параметров. Могут быть указаны целочисленные значения, но вероятность ошибки будет меньше, а вероятность менее ясна. Не все значения должны быть использованы, возможно, sone являются частными или использовались ранее, а затем удалены или по другой произвольной причине.