iOS/object-c: 枚举类型 enum,NS_ENUM,NS_OPTIONS

本文详细介绍了iOS开发中枚举类型的定义方式及其应用场景,包括基本的枚举定义、位移操作枚举定义以及如何使用NS_ENUM和NS_OPTIONS宏进行枚举类型的定义。

一般情况下,我们采用C风格的enum关键字可以定义枚举类型。

enum{   
    UIViewAnimationTransitionNone,  
    UIViewAnimationTransitionFlipFromLeft,  
    UIViewAnimationTransitionFlipFromRight,  
    UIViewAnimationTransitionCurlUp,  
    UIViewAnimationTransitionCurlDown,  
} UIViewAnimationTransition;  


//位移操作枚举定义  
enum {  
    UIViewAutoresizingNone                 = 0,  
    UIViewAutoresizingFlexibleLeftMargin   = 1 << 0,  
    UIViewAutoresizingFlexibleWidth        = 1 << 1,  
    UIViewAutoresizingFlexibleRightMargin  = 1 << 2,  
    UIViewAutoresizingFlexibleTopMargin    = 1 << 3,  
    UIViewAutoresizingFlexibleHeight       = 1 << 4,  
    UIViewAutoresizingFlexibleBottomMargin = 1 << 5  
};  
typedef NSUInteger UIViewAutoresizing;//使用NSUInteger的地方可以使用UIViewAutoresizing,//UIViewAutoresizing相当于NSUInteger的一个别名使用。  
//因此一个UIViewAutoresizing的变量可以直接赋值给NSUInteger 

枚举值一般是4个字节的int值,在64位系统上是8个字节。

在iOS6和Mac OS 10.8以后Apple引入了两个宏来重新定义这两个枚举类型,实际上是将enum定义和typedef合二为一,并且采用不同的宏来从代码角度来区分。

NS_OPTIONS一般用来定义位移相关操作的枚举值,我们可以参考UIKit.Framework的头文件,可以看到大量的枚举定义。

typedef NS_ENUM(NSInteger, UIViewAnimationTransition) {  
    UIViewAnimationTransitionNone,//默认从0开始  
    UIViewAnimationTransitionFlipFromLeft,  
    UIViewAnimationTransitionFlipFromRight,  
    UIViewAnimationTransitionCurlUp,  
    UIViewAnimationTransitionCurlDown,  
};  

typedef NS_OPTIONS(NSUInteger, UIViewAutoresizing) {  
    UIViewAutoresizingNone                 = 0,  
    UIViewAutoresizingFlexibleLeftMargin   = 1 << 0,  
    UIViewAutoresizingFlexibleWidth        = 1 << 1,  
    UIViewAutoresizingFlexibleRightMargin  = 1 << 2,  
    UIViewAutoresizingFlexibleTopMargin    = 1 << 3,  
    UIViewAutoresizingFlexibleHeight       = 1 << 4,  
    UIViewAutoresizingFlexibleBottomMargin = 1 << 5  
};  

这两个宏的定义在Foundation.framework的NSObjCRuntime.h中:

#if (__cplusplus && __cplusplus >= 201103L && (__has_extension(cxx_strong_enums) || __has_feature(objc_fixed_enum))) || (!__cplusplus && __has_feature(objc_fixed_enum))  
#define NS_ENUM(_type, _name) enum _name : _type _name; enum _name : _type  
#if (__cplusplus)  
#define NS_OPTIONS(_type, _name) _type _name; enum : _type  
#else  
#define NS_OPTIONS(_type, _name) enum _name : _type _name; enum _name : _type  
#endif  
#else  
#define NS_ENUM(_type, _name) _type _name; enum  
#define NS_OPTIONS(_type, _name) _type _name; enum  
#endif  

typedef NS_ENUM(NSInteger, UIViewAnimationTransition) {  

展开得到

typedef enum UIViewAnimationTransition : NSInteger UIViewAnimationTransition;  
enum UIViewAnimationTransition : NSInteger {  

实例

枚举的定义还支持位运算的方式定义,如下: 等于号后面必须等于1

typedef NS_ENUM(NSInteger, Test) {

    TestA = 1, //1 1 1

    TestB = 1 << 1, //2 2 10 转换成 10进制 2

    TestC = 1 << 2, //4 3 100 转换成 10进制 4

    TestD = 1 << 3, //8 4 1000 转换成 10进制 8

    TestE = 1 << 4 //16 5 10000 转换成 10进制 16

};
typedef int ImDrawFlags; // -> enum ImDrawFlags_ // Flags: for ImDrawList functions typedef int ImDrawListFlags; // -> enum ImDrawListFlags_ // Flags: for ImDrawList instance typedef int ImFontFlags; // -> enum ImFontFlags_ // Flags: for ImFont typedef int ImFontAtlasFlags; // -> enum ImFontAtlasFlags_ // Flags: for ImFontAtlas typedef int ImGuiBackendFlags; // -> enum ImGuiBackendFlags_ // Flags: for io.BackendFlags typedef int ImGuiButtonFlags; // -> enum ImGuiButtonFlags_ // Flags: for InvisibleButton() typedef int ImGuiChildFlags; // -> enum ImGuiChildFlags_ // Flags: for BeginChild() typedef int ImGuiColorEditFlags; // -> enum ImGuiColorEditFlags_ // Flags: for ColorEdit4(), ColorPicker4() etc. typedef int ImGuiConfigFlags; // -> enum ImGuiConfigFlags_ // Flags: for io.ConfigFlags typedef int ImGuiComboFlags; // -> enum ImGuiComboFlags_ // Flags: for BeginCombo() typedef int ImGuiDockNodeFlags; // -> enum ImGuiDockNodeFlags_ // Flags: for DockSpace() typedef int ImGuiDragDropFlags; // -> enum ImGuiDragDropFlags_ // Flags: for BeginDragDropSource(), AcceptDragDropPayload() typedef int ImGuiFocusedFlags; // -> enum ImGuiFocusedFlags_ // Flags: for IsWindowFocused() typedef int ImGuiHoveredFlags; // -> enum ImGuiHoveredFlags_ // Flags: for IsItemHovered(), IsWindowHovered() etc. typedef int ImGuiInputFlags; // -> enum ImGuiInputFlags_ // Flags: for Shortcut(), SetNextItemShortcut() typedef int ImGuiInputTextFlags; // -> enum ImGuiInputTextFlags_ // Flags: for InputText(), InputTextMultiline() typedef int ImGuiItemFlags; // -> enum ImGuiItemFlags_ // Flags: for PushItemFlag(), shared by all items typedef int ImGuiKeyChord; // -> ImGuiKey | ImGuiMod_XXX // Flags: for IsKeyChordPressed(), Shortcut() etc. an ImGuiKey optionally OR-ed with one or more ImGuiMod_XXX values. typedef int ImGuiListClipperFlags; // -> enum ImGuiListClipperFlags_// Flags: for ImGuiListClipper typedef int ImGuiPopupFlags; // -> enum ImGuiPopupFlags_ // Flags: for OpenPopup*(), BeginPopupContext*(), IsPopupOpen() typedef int ImGuiMultiSelectFlags; // -> enum ImGuiMultiSelectFlags_// Flags: for BeginMultiSelect() typedef int ImGuiSelectableFlags; // -> enum ImGuiSelectableFlags_ // Flags: for Selectable() typedef int ImGuiSliderFlags; // -> enum ImGuiSliderFlags_ // Flags: for DragFloat(), DragInt(), SliderFloat(), SliderInt() etc. typedef int ImGuiTabBarFlags; // -> enum ImGuiTabBarFlags_ // Flags: for BeginTabBar() typedef int ImGuiTabItemFlags; // -> enum ImGuiTabItemFlags_ // Flags: for BeginTabItem() typedef int ImGuiTableFlags; // -> enum ImGuiTableFlags_ // Flags: For BeginTable() typedef int ImGuiTableColumnFlags; // -> enum ImGuiTableColumnFlags_// Flags: For TableSetupColumn() typedef int ImGuiTableRowFlags; // -> enum ImGuiTableRowFlags_ // Flags: For TableNextRow() typedef int ImGuiTreeNodeFlags; // -> enum ImGuiTreeNodeFlags_ // Flags: for TreeNode(), TreeNodeEx(), CollapsingHeader() typedef int ImGuiViewportFlags; // -> enum ImGuiViewportFlags_ // Flags: for ImGuiViewport typedef int ImGuiWindowFlags; // -> enum ImGuiWindowFlags_ // Flags: for Begin(), BeginChild()
最新发布
09-11
这段代码来自 [**Dear ImGui**](https://github.com/ocornut/imgui)(一个用于 C++ 的即时模式 GUI 库),它使用 `typedef int` 来为各种枚举标志(flags)定义类型别名,使得在代码中可以以位掩码(bitmask)的方式组合多个选项。 --- ### 为什么使用 `typedef int` 在 C/C++ 中,枚举值默认是 `int` 类型,而标志位(flags)通常通过按位或(`|`)来组合多个选项。使用 `typedef int` 而不是真正的 `enum` 是为了: 1. **便于组合标志位**:例如 `ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove` 2. **兼容性好**:C++ 中 `enum` 和 `int` 之间不能直接赋值,除非使用 `enum class : int` 或者这里的方式。 3. **历史原因与轻量化设计**:ImGui 作为轻量级库,避免了复杂的类型系统。 --- ### 示例说明 以 `ImGuiWindowFlags` 为例: ```cpp typedef int ImGuiWindowFlags; ``` 你可以这样使用它: ```cpp ImGui::Begin("My Window", nullptr, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove); ``` 这表示打开一个不可调整大小且不可移动的窗口。 --- ### 实际上对应的枚举类型(伪代码) 虽然这些 `typedef int` 没有显式定义为 `enum`,但它们的值通常定义为类似下面的枚举: ```cpp enum ImGuiWindowFlags_ { ImGuiWindowFlags_None = 0, ImGuiWindowFlags_NoTitleBar = 1 << 0, // 1 ImGuiWindowFlags_NoResize = 1 << 1, // 2 ImGuiWindowFlags_NoMove = 1 << 2, // 4 ImGuiWindowFlags_NoScrollbar = 1 << 3, // 8 ImGuiWindowFlags_NoScrollWithMouse = 1 << 4, // 16 // ... 其他标志 }; ``` --- ### 使用方式详解 ```cpp ImGuiWindowFlags flags = ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove; ImGui::Begin("Window", nullptr, flags); ``` - `flags` 是一个 `int` 类型,它的值是两个标志位的按位或结果。 - `ImGui::Begin` 内部会检查这些位是否被设置。 --- ### 为什么要这样做? - **性能**:使用 `int` 比 `std::bitset` 或 `std::vector` 更高效。 - **可读性**:通过命名标志位,提高代码可读性。 - **组合性**:支持多个选项组合,例如 `ImGuiTableFlags_RowBg | ImGuiTableFlags_BordersOuter` --- ### 完整示例(展示一个带标志的窗口) ```cpp #include "imgui.h" #include "imgui_impl_glfw.h" #include "imgui_impl_opengl3.h" #include <GLFW/glfw3.h> int main() { // 初始化 GLFW 和 ImGui(略去细节) // ... bool show_demo_window = true; while (!glfwWindowShouldClose(window)) { // 开始一帧 ImGui_ImplOpenGL3_NewFrame(); ImGui_ImplGlfw_NewFrame(); ImGui::NewFrame(); // 创建一个不可调整大小、不可移动的窗口 ImGuiWindowFlags flags = ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove; ImGui::Begin("My Window", &show_demo_window, flags); ImGui::Text("Hello, world!"); ImGui::End(); // 渲染 ImGui::Render(); // ... } // 清理资源 return 0; } ``` --- ### 常见标志位分类举例 | 类型 | 常用标志 | |------|----------| | `ImGuiWindowFlags` | `NoTitleBar`, `NoResize`, `NoMove`, `NoScrollbar`, `NoCollapse` | | `ImGuiTableFlags` | `SizingFixedFit`, `BordersOuter`, `RowBg`, `Resizable` | | `ImGuiInputTextFlags` | `ReadOnly`, `Password`, `AutoSelectAll`, `EnterReturnsTrue` | | `ImGuiTreeNodeFlags` | `OpenOnArrow`, `OpenOnDoubleClick`, `Leaf`, `Selected` | --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值