NS_ENUM & NS_OPTIONS
When everything is an object, nothing is.
So, there are a few ways you could parse that, but for the purposes of this article, this is all to say: sometimes it's nice to be able to drop down to the C layer of things.
Yes--that non-objective part of our favorite Smalltalk-inspired hybrid language, C can be a great asset. It's fast, it's battle-tested, it's the very foundation of modern computing. But more than that, C is the escape hatch for when the Object-Oriented paradigm cracks under its own cognitive weight.
Static functions are nicer than shoe-horned class methods.
Enums are nicer than string constants.
Bitmasks are nicer than arrays of string constants.
Preprocessor directives are nicer than runtime hacks.
A skilled Objective-C developer is able to gracefully switch between Objective and Procedural paradigms, and use each to their own advantage.
And on that note, this week's topic has to do with two simple-but-handy macros: NS_ENUM andNS_OPTIONS.
Introduced in Foundation with iOS 6 / Mac OS X 10.8, the NS_ENUM and NS_OPTIONS macros are the new, preferred way to declare enum types.
If you'd like to use either macro when targeting a previous version of iOS or OS X, you can simply inline like so:
#ifndef NS_ENUM
#define NS_ENUM(_type, _name) enum _name : _type _name; enum _name : _type
#endif
enum, or enumerated value types, are the C way to define constants for fixed values, like days of the week, or available styles of table view cells. In an enum declaration, constants without explicit values will automatically be assigned values sequentially, starting from 0.
There are several legal ways that enums can be defined. What's confusing is that there are subtle functional differences between each approach, and without knowing any better, someone is just as likely to use them interchangeably.
For instance:
enum {
UITableViewCellStyleDefault,
UITableViewCellStyleValue1,
UITableViewCellStyleValue2,
UITableViewCellStyleSubtitle
};
...declares integer values, but no type.
Whereas:
typedef enum {
UITableViewCellStyleDefault,
UITableViewCellStyleValue1,
UITableViewCellStyleValue2,
UITableViewCellStyleSubtitle
} UITableViewCellStyle;
...defines the UITableViewCellStyle type, suitable for specifying the type of method parameters.
However, Apple had previously defined all of their enum types as:
typedef enum {
UITableViewCellStyleDefault,
UITableViewCellStyleValue1,
UITableViewCellStyleValue2,
UITableViewCellStyleSubtitle
};
typedef NSInteger UITableViewCellStyle;
...which ensures a fixed size for UITableViewCellStyle, but does nothing to hint the relation between the aforementioned enum and the new type to the compiler.
Thankfully, Apple has decided on "One Macro To Rule Them All" with NS_ENUM.
NS_ENUM
Now, UITableViewCellStyle is declared with:
typedef NS_ENUM(NSInteger, UITableViewCellStyle) {
UITableViewCellStyleDefault,
UITableViewCellStyleValue1,
UITableViewCellStyleValue2,
UITableViewCellStyleSubtitle
};
The first argument for NS_ENUM is the type used to store the new type. In a 64-bit environment,UITableViewCellStyle will be 8 bytes long--same as NSInteger. Make sure that the specified size can fit all of the defined values, or else an error will be generated. The second argument is the name of the new type (as you probably guessed). Inside the block, the values are defined as usual.
This approach combines the best of all of the aforementioned approaches, and even provides hints to the compiler for type-checking and switch statement completeness.
NS_OPTIONS
enum can also be used to define a bitmask. Using a convenient property of binary math, a single integer value can encode a combination of values all at once using the bitwise OR (|), and decoded with bitwise AND (&). Each subsequent value, rather than automatically being incremented by 1 from 0, are manually given a value with a bit offset: 1 << 0, 1 << 1, 1 << 2, and so on. If you imagine the binary representation of a number, like 10110 for 22, each bit can be though to represent a single boolean. In UIKit, for example, UIViewAutoresizing is a bitmask that can represent any combination of flexible top, bottom, left, and right margins, or width and height.
Rather than NS_ENUM, bitmasks should now use the NS_OPTIONS macro.
The syntax is exactly the same as NS_ENUM, but this macro alerts the compiler to how values can be combined with bitmask |. Again, you must be careful that all of the enumerated values fit within the specified type.
NS_ENUM and NS_OPTIONS are handy additions to the Objective-C development experience, and reaffirm the healthy dialectic between its objective and procedural nature. Keep this in mind as you move forward in your own journey to understand the logical tensions that underpin everything around us.
NS_ENUM & NS_OPTIONS的更多相关文章
- iOS: 枚举类型 enum,NS_ENUM,NS_OPTIONS
一般情况下,我们采用C风格的enum关键字可以定义枚举类型. enum{ UIViewAnimationTransitionNone, UIViewAnimationTransitionFlipFro ...
- iOS/object-c: 枚举类型 enum,NS_ENUM,NS_OPTIONS
一般情况下,我们采用C风格的enum关键字可以定义枚举类型. enum{ UIViewAnimationTransitionNone, UIViewAnimationTransitionFlipFro ...
- iOS中的枚举:enum, NS_ENUM, NS_OPTIONS的使用区别
1.enum可以声明一般类型和位掩码(bitmasked)类型 例如: enum Test{// 一般枚举 TestA, TestB, TestC, }; enum{// 匿名枚举 TestA, Te ...
- Object-C: 枚举
摘自:http://coffeeandsandwich.com/?p=8 在 iOS 6 和 Mac OS X 10.8 以前,定义枚举类型的方式如下: typedef enum the_enum_n ...
- SDWebImage之SDWebImageCompat
SDWebImageCompat 是SDWebImage 的配置文件,里面利用条件编译对Apple 的各个平台进行了兼容.从源码中可以看到SDWebImage 支持当前的MAC/iOS/TV/WATC ...
- <笔记>Effective Objective-C 2.0 编写高质量iOS与
1. 内存管理-引用计数 2. 非对象类型 int float double char 3.运行时--编译器(编译时)函数调用 4.@class 缩短编译时间,降低依赖,耦合 5.使用字面量而不是 ...
- iOS.C
iOS开发中C语言的应用: 1. NS_ENUM & NS_OPTIONS http://nshipster.com/ns_enum-ns_options/
- clang 编译 OC
clang -fobjc-arc -framework Foundation helloworld.m -o helloworld.out OVERVIEW: clang LLVM compiler ...
- YYModel源代码阅读--基础知识
这段时间因为工作需要,阅读了YYModel这个开源框架,至于它能做什么,最直白的讲述就是JSON与Model之间的相互转化. 源代码在Github,大家可以自行git clone或者download. ...
随机推荐
- 学会简单使用log4j
简单配置: ### ??Logger?????????? ### ##log4j.rootLogger=debug, stdout,logfile log4j.rootLogger=debug, st ...
- openssl安装
www.openssl.orgconfigure the environment:<pre lang="bash" escaped="true">t ...
- JS面向对象组件(二)--Javascript原型链
原型链 : 实例对象与原型之间的连接,叫做原型链 –__proto__( 隐式连接 ),这就是原型链,平时我们是看不到的. 原型链的最外层 : Object.prototype function Aa ...
- Python中的sorted函数以及operator.itemgetter函数
operator.itemgetter函数operator模块提供的itemgetter函数用于获取对象的哪些维的数据,参数为一些序号(即需要获取的数据在对象中的序号),下面看例子. a = [1,2 ...
- Java Web 乱码
1.mySql编码 2.jdbc编码 http://www.blogjava.net/NicholasEcho/archive/2008/11/03/238310.html ----- 1.HttpG ...
- Informatica9.6.1在Linux Red Hat 5.8上安装遇到的有关问题整理_2
2. 产品安装过程提示Ping Domain Error 1)错误日志: Pinging domain... 8:19:22 AM ********************************** ...
- centos6.5 安装fctix 五笔输入法
摸索了大半晚上,终于搞定,网上的东西看了N多篇不是这问题就是那问题,看来不同的OS下,小白我还是太嫩了些. 1,删除输入法,这一步是清除输入法,操作完成后,桌面/系统/首先项/输入法的IM Choos ...
- 浏览器的DNS缓存
通过设置hosts文件可以强制指定域名对应的IP,当修改hosts文件,想要浏览器生效,最直接的方法关闭浏览器后重新开启:如果不想重启浏览器,只需要清空浏览器的DNS缓存即可.清空DNS缓存在chro ...
- loadrunner之C语言编程
一.常量定义 #define COUNT 100 //定义全局常量#define SALARY 4000 Action(){ int total; total = C ...
- 九度 Online Judge 之《剑指 Offer》一书相关题目解答
前段时间准备华为机试,正好之前看了一遍<剑指 Offer>,就在九度 Online Judge 上刷了书中的题目,使用的语言为 C++:只有3题没做,其他的都做了. 正如 Linus To ...