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 << 01 << 11 << 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.

欢迎加群互相学习,共同进步。QQ群:iOS: 58099570 | Android: 330987132 | Go:217696290 | Python:336880185 | 做人要厚道,转载请注明出处!http://www.cnblogs.com/sunshine-anycall/p/3174003.html
相关文章
ValidationError: Invalid options object. Dev Server has been initialized using an options object tha
ValidationError: Invalid options object. Dev Server has been initialized using an options object tha
|
存储 Java 开发工具
Warning: Mapping new ns http://schemas.android.com/repository/android/common/02 to old ns http://sch
构建警告:将新 ns 映射到旧 ns 尝试删除并重新安装 SDK 平台。删除 ~\Android\Sdk\platforms 中的文件夹并下载您需要的 SDK。 编辑:以上以某种方式解决了之前的问题,但是当更新更多外部包时,我再次遇到了同样的问题。这一次,删除 SDK 平台不起作用。相反,我在项目的两个位置更新了 Gradle:
1997 0
|
关系型数据库 MySQL Java
The server time zone value ‘锟叫癸拷锟斤拷\u05FC时锟斤拷‘ is unrecognized or represents more than one time zone
The server time zone value ‘锟叫癸拷锟斤拷\u05FC时锟斤拷‘ is unrecognized or represents more than one time zone
The server time zone value ‘锟叫癸拷锟斤拷\u05FC时锟斤拷‘ is unrecognized or represents more than one time zone
tdav_converter_video.cxx:49:9: error: ‘uint8’ does not name a type; did you mean ‘uint’?
tdav_converter_video.cxx:49:9: error: ‘uint8’ does not name a type; did you mean ‘uint’?
103 0
Sap Ds Data is not available. Increase the time-out interval values in Debug | Options
Sap Ds Data is not available. Increase the time-out interval values in Debug | Options
107 0
error:‘struct vm_fault‘ has no member named ‘virtual_address‘
error:‘struct vm_fault‘ has no member named ‘virtual_address‘
127 0
error:‘struct vm_fault‘ has no member named ‘virtual_address‘
python 类型转换 object to datetime64[ns],timedelta64[ns] to float
python 类型转换 object to datetime64[ns],timedelta64[ns] to float
python 类型转换 object to datetime64[ns],timedelta64[ns] to float
SAP WM 为Storage Type 004激活SUM报错 - Storage types without pick-point stor.type require partial pallet
SAP WM 为Storage Type 004激活SUM报错 - Storage types without pick-point stor.type require partial pallet
SAP WM 为Storage Type 004激活SUM报错 - Storage types without pick-point stor.type require partial pallet
etag flag setting in metadata MPC_EXT
Created by Wang, Jerry, last modified on Jan 15, 2015
etag flag setting in metadata MPC_EXT