Navigation

NS_ENUM and NS_OPTIONS

Tuesday, November 27th, 2012

If you, like most programmers, are curious and detail-oriented you may have noticed that this:

typedef 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;

Has, in iOS 6, turned into this:

typedef NS_ENUM(NSInteger, UIViewAnimationTransition) {
    UIViewAnimationTransitionNone,
    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
};

And maybe you even clicked through to the definition of NS_ENUM and NS_OPTIONS and saw this:

#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

At which point you almost certainly threw up your hands and went back to work.

Recently I had some free time so I broke down this enum situation and also included some of the history and present and also maybe even a little bit of the future of enumerated types in Objective-C.

The Way Things Used To Be

The iOS 5.1 definition of UIViewAnimationTransition is pretty standard and should be comprehensible to any C programmer. It defines an anonymous enum and immediately declares a typedef of that enum to a new type name. This allows the enum to be referenced using only the type name — were the enum to be named in the traditional way (enum UIViewAnimationTransition {) the enum keyword would have to be supplied (enum UIViewAnimationTransition) when declaring values of that type, e.g. in method signatures. The typedef-of-anonymous-enum pattern is standard practice in good, modern C code.

The iOS 5.1 definition of UIViewAutoresizing is a little more interesting but should also be comprehensible even if its motivations are recondite. Like the first example it too defines an anonymous enum. However, it does not typedef the enum itself. Instead it declares the type UIViewAutoresizing as a typedef of NSUInteger. Comprehensible, but recondite.

C Standard Arcanum

From the C Standard, 1999 edition, §6.7.2.2.4:1

Each enumerated type shall be compatible with char, a signed integer type, or an unsigned integer type. The choice of type is implementation-defined2, but shall be capable of representing all the values of the members of the enumeration.

If you’re quick-witted you may already have caught the plot: because the standard offers no guarantees about an enum’s signedness and because UIViewAutoresizing declares explicit values for its identifiers which are designed to be combined with the bitwise-or operator and because the results of bitwise operations on signed integers is also implementation-defined (what would -1 | 1 mean anyway) allowing the compiler pick the type of an enum automatically is unsafe.

It turns out this is a fairly common problem so the following workaround was developed: leave the enum anonymous — its identifiers are still valid — and declare the type as a typedef of an integer type of known size and signedness. The advantages of this should be obvious but come with a significant downside: the compiler no longer knows about the connection between the identifiers and the type. This precludes all sorts of lovely warnings (or-ing values from two different enums, missing cases in a switch statement) and also likely, depending on your editor, hinders autocomplete suggestions.

Clearly not an ideal situation.

The Way Things Are

In C++11 and also in more recent versions of Objective-C there is a solution to this: fixed-type enums. The syntax for this looks like this:

enum MyEnum : NSUInteger { ... };

With that in mind, let’s take another look at the macro sludge pasted above.

Base Case

#else
#define NS_ENUM(_type, _name) _type _name; enum
#define NS_OPTIONS(_type, _name) _type _name; enum
#endif

The last four lines, reproduced above, merely define the status quo. If this still looks like gibberish to you, recall how the macro is used on context (e.g. typedef NS_ENUM(NSInteger, UIViewAnimationTransition) {).

Objective-C

Let’s assume that the compiler is operating in Objective-C mode and the fixed enum feature is enabled. We’d see the following definitions of NS_ENUM and NS_OPTIONS:

#define NS_ENUM(_type, _name) enum _name : _type _name; enum _name : _type
#define NS_OPTIONS(_type, _name) enum _name : _type _name; enum _name : _type

These are identical. If we expand one of our previous examples, we get the following:

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

(Line break added by yours truly.) Straightforward enough with the caveat that the type of the enum is required to be repeated in the typedef because the enum is forward declared.

C++

If the compiler is operating in C++11 or Objective-C++11 mode, the definitions are a little bit different:

#define NS_ENUM(_type, _name) enum _name : _type _name; enum _name : _type
#define NS_OPTIONS(_type, _name) _type _name; enum : _type

Eagle-eyed readers will have already noticed that definition of NS_OPTIONS is the same as the base case above and indeed this is where NS_OPTIONS differs from NS_ENUM. In perusing the headers of UIKit, it seems that NS_OPTIONS is used exclusively when declaring enums with explicit values for their identifiers. I’m not sure what rule of C++ this violates and frankly don’t particularly feel like investigating, but clearly, it’s a problem. (Mark Rowe has chimed in with the answer.)

The Way Things Will Be

In your own code, I would recommend the following:

  • Declare your enums as typedef enum : NSUInteger { ... } MyEnum;. It’s a simple and straightforward extension to the very common typedef-of-anonymous-enum pattern.
  • If your headers need to support compilation in Objective-C++ mode, use the NS_ENUM and NS_OPTIONS macros. You’ll need to experiment to figure out exactly where you need to use NS_OPTIONS as a fallback but NS_ENUM should be preferred wherever possible.

  1. Chapter and verse courtesy of Patrick Thomson. Thanks dude. 

  2. Patrick wrote in to add: “If you would accept suggestions, I would explain how implementation-defined behavior differs from undefined behavior (viz. compilers are required to describe implementation-defined behavior).” 

Comments (4)

2013 iPads

Tuesday, October 23rd, 2012

Apple is a very predictable company.

Apple won’t be updating the iPads again until Fall 2013. These fall, pre-holidays announcements have been Apple’s bread and butter for over ten years now, going back to the fall iPod and music events. Beginning with Apple’s departure from Macworld Expo, held every January, Apple has been seeking to shift its product schedule1 to align better with the holiday season. The awkwardness of the April update schedule of the iPads have been on until now was, if anything, further proof of the need to focus around the holiday season. The current lineup will remain unchanged through the spring and summer.2

When they do update the iPad line, I’m predicting a breakdown like this:

  • 5th generation iPad. As thin and light as the iPad 2. (Finally.)
  • The iPad 2 disappears.
  • An all-new iPad mini with retina display. Slightly thicker. And all the usual tweaks and improvements Apple usually makes with each model — camera improvements, smart cover improvements, etc.
  • 1st generation iPad mini as a lower-cost option.

The main detail missing here is price. If Apple is to replace the iPad 2 with a 5th generation iPad, the lowest priced model will be $399. This seems plausible given the assumption that it is mostly the same as the 4th generation iPad but thinner and smaller.

But what about the 1st generation iPad mini? I think a safe bet is $279. But I could see Apple pricing it as low as $249. Even at that low of a price point, I’m not too worried about iPod touch cannibalization. Previous generation iPod touches are $199. A previous generation 16GB iPad mini at $249 would not be a significant threat to a brand new 32GB iPod touch at $299.

Now, I could be really wrong. Apple could leave the 4th generation iPad around as the cheaper option and push forward even further technically with a 5th generation iPad, thinness be damned. Anything could happen; Apple is a very unpredictable company.


  1. Let’s leave aside Macs for the time being. Not only are they more beholden to Intel’s schedule for new processor releases but Macs do a significant amount of back-to-school business, having some form of update in the summer makes ense, especially for models popular among students like laptops. 

  2. Yes, this means they’re selling iPads with 30-pin dock connectors. But they’re also selling iPods and iPhones with the same connectors and will be for quite a while. The transition to Lightning will take time. 

Comments Off

Çingleton Deux

Monday, October 22nd, 2012

I have spent a fall weekend in Chicago nearly every year since 2005. But this year I found myself in Montreal, Quebec for Çingleton Deux, a self-styled “three-day Mac developer get-together”.

Old Montreal, the Montreal neighborhood where Çingleton was located this year, is on the one hand very beautiful. The Saint Lawrence river is picturesque, and the whole of Old Montreal has a wet, rain-slick aspect befitting a city that grew up on a river bank. It reminded me of what I imagined Lake-town from The Hobbit would have been like. The architecture is gorgeous; a little bit of Old Europe plopped down into North America. The Hotel Nelligan itself is a beautiful building full of exposed brick and other stone surfaces. On the other hand, the developer conference nightlife staples — cheap dive bars complete with barflies and breakfast-all-night greasy spoons — are nowhere to be found in Old Montreal. The locals seem to be mostly posh bridge-and-tunnel types, with a generous sprinkling of tourists. (After a few days we found some reliable haunts, and it’s been hinted that attendees may be armed with a map next year.)

I did like the area outside of Old Montreal a lot more. It is like any other North American city but with this bizarre French patina. I have a million little anecdotes I could share, but it is only in the aggregate experience that it really stands out. But trust me when I say that Montrealers are more than just French-speaking Canadians.

Oh, and if you like chili cheese fries you will like poutine. I promise.

The weather here was autumnal: cool but not cold. It felt fitting then that baseball was such an omnipresent topic, especially dramatic playoffs baseball. Aside from technology, it was the second most popular topic of conversation. The irony of the watching former Expos being knocked out of the playoffs, their second overall appearance and their first since 1981, all while in Montreal, was not lost on me.

An observation: the realities of a tournament mean you cannot just root for your team. My Oakland A’s were eliminated shortly after I arrived in Montreal, after an absolutely incredible season. If I had stopped paying attention to baseball when the A’s were eliminated and if I hadn’t also been paying attention to the wider baseball situation all season, I would have missed a lot of the drama of the postseason.

I would forgive you if so far you have the impression that I went on a vacation with a bunch of my friends rather than attend a technology conference. Because, well, that’s kind of what I did. The people at Çingleton were all absolutely delightful. At a small conference for a small community it’s really easy to “clique up”. I have had trouble with that myself in the past — just hanging out with a small group of folks for the entire conference. But I don’t feel like that happened at Çingleton. Sure, I saw a lot of the same old faces; that was indeed one of the best parts about the conference. But there also were also a lot of new faces, and a lot of the new faces were mixing with those same old faces. And finally, I really don’t feel like this mixing happened out of sense of fairness or from trying to seeing everyone for the sake of seeing everyone — it certainly didn’t in my case — but because everyone new had an exciting and fresh perspective and an interesting story.

Just like with baseball, this type of wider awareness is really important. Both the speakers and myself spent a lot of time talking about meta-trends and new types of platforms and technologies and such. Ending up stuck in your own little world thinking about your own little problems is can be really dangerous. Instead, I recommend seeking a broad perspective. Enjoy surveying the landscape from mountaintops from time to time. Don’t spend all your time in the underbrush.

Ultimately though, my biggest takeaway has been seeing some of my cynicism evaporate. Although the official theme of the talks at Çingleton this year was scaling, one of the other big themes was change. Particularly this idea that change happens to you, whether you like it or not, or even whether you are ready for it or not. This idea is at the root of a lens which has surprisingly potent for clearing up a particular cynicism I see both in myself and in wider the technology world right now. This cynicism that sneers at the “change the world” attitude adopted by the startups of the current bubble.

But the problem with cynicism is that it still accepts the axioms of the argument to which it is reacting. It is sophomoric. It offers no alternative.

Instead, I’m starting to view things through this new lens. A lens which offers its own perspectives and predictions about the future and about technology’s worth. To summarize: if instead of seeking to be the agent of change, we accept that change is happening to us. (This is especially relevant for those of us who are swimming in the increasingly larger and larger Apple pond.) Viewing the world through this light, we now have the ability perform a bit of aikido. Instead of raging against this particular, ultimately temporary, tide we can use the chaotic, changing nature of the industry to our advantage. We can seize authority instead of waiting for it to be granted. We can try experiments. And if they don’t work, we can iterate. We can revise. We can, provided we remain humble, even revisit old approaches which may now work better.

Imagine me at customs. “Yes, sir, I have something to declare: a new sense of agency and direction.”

Comments Off

AirPlay Apps

Friday, June 8th, 2012

I think it’d be cool if Apple TV apps, instead of running on the Apple TV, “streamed” off your phone with AirPlay.

The current situation is that iOS apps can AirPlay to an Apple TV. This essentially gives you a second UIWindow on the Apple TV you can put whatever content in — slideshow, movie, etc.

This is almost all of the way there — here’s what I think Apple could add:

  • Set of UI classes to make developing an Apple TV–native interface easy
  • Allow apps to receive events from the remote
  • Allow apps to be started from the Apple TV

That last one is key. You sit down in front of your TV and “channels” that represent the AirPlay-enabled apps you have on your phone appear. You select one with the remote and the app launches on your phone (silently) and now you’re streaming content to the Apple TV.

There are certainly problems and complications with this approach. But it could be an interesting way to keep the Apple TV cheap and affordable while also allowing the long tail network effects of the App Store to get a beachhead on the Apple TV.

Comments (2)

Respect your cues

Sunday, March 25th, 2012

My friend Amy Hoy wrote about habits recently:

A habit isn’t a thing, it’s three things: a cue, a routine, and a reward. And it’s not three things, it’s a loop.

The routine is the practiced set of actions you take — the thing we all call “a habit.” The cue is the trigger on the gun of routine, the thing that says chop chop, brush brush. The reward is the nice thing you get at the end. Behaviorism aside, the human brain really does wire itself up to react to rewards.

Put these 3 things together, in a loop, and run it again & again, and you have the makings of an automatic habit.

Like a lot of people, I have lots of “shoulds” in my life — I should take my allergy medication, I should send out invoices, I should make steady progress ahead of a looming deadline — and worrying about all of those is a source of great anxiety and stress for me. But in all that worrying about routines, and despite all the various rewards I’ve dangled in front of myself, I’ve never really thought about cues as a concrete part of the habit process before.

In the two days since I read that post I’ve come up with a catchphrase that summarizes my new attitude towards habit building: respect your cues. What that means is that if I encounter a cue — either a new one I’ve consciously chosen, or a natural one that bubbles up from my unconscious — I absolutely should not ignore it.

As an example of the latter, if I walk into my room and cringe at the clothes on the floor, I should put some of them away. I don’t have to go on a cleaning spree, but I can at least hang one jacket up.

As for the former — new habits I’m trying to create — I now start thinking about the cues I’ve set up for myself. An excellent example is invoicing. Normally I invoice twice a month, however my current client wants invoices only once a month and on a slightly different date than when I usually send them out. I do have a calendar event set up to remind me to send out invoices, but it’s not on the right dates. Instead of training myself to take care of invoices promptly, I’m training myself to ignore my invoicing calendar event! That’s no good.

This is all still a work in progress — after all I’ve only been at this for two days — but I think I’m at the beginning of an important journey. And now if you’ll excuse me, I have a calendar event to update.

Comments (2)

And nobody can stop them

Thursday, February 9th, 2012

Mark Sample:

Whether it’s Radiohead, Louis CK, or Tim Schafer, already successful people will always find new ways to fund and distribute their products.

This kind of crowdfunding poopooing grinds my gears.

In the video for the Schafer-led Kickstarter project that Sample is referencing, Schafer talks repeatedly about how he would have loved to create more adventure games, but couldn’t, and can’t, get a traditional publisher to work with him. This is not news: he’s expressed a similar sentiment in interviews for years — adventure games are exactly as dead as publishers say they are.

The scenario described above (so far) has played itself out across industries for decades, but particularly in the world of popular music — for so long a hit-based business with sales driven by radio airplay. Popular, successful artists on the train of a waning fad had two choices: try to hop aboard the next train and take a risk (see: innumerable ’70s bands in the ’80s) or refuse and be forced out of the music business entirely. (see: ibid.)

Here’s what’s changed:

  1. Popular artists can now connect directly with their fans
  2. Who can help them fund projects agreeable to both artist and fan alike
  3. And nobody can stop them

This is a new development and is part of an important shift away from the mass-market, multicast mediae that dominated culture most of the 20th century.

That upending is worthy of celebration, come whatever else may.

Comments (1)

Goodbye, Steve

Wednesday, October 5th, 2011

I would not be here today, doing what I do, if not for Steve Jobs. Considering I never met the man, he had an incredible impact on my career, my outlook on life, and my definition of success.

Goodbye, Steve. Rest easy.

See also, Remembering Steve Jobs on Nullary Sources.

Comments Off

Busy

Wednesday, September 7th, 2011

I’ve been busy — really busy.

Much of that energy obviously has been going in to running Springs & Struts, my Mac and iOS consulting business. I’ve been using the Springs & Struts name for over two and a half years now and 2011 has been our best year yet. I’ve shipped several apps for happy clients already this year. I’ve also begun to experiment with using subcontractors (and being a subcontractor myself), an effort which has been quite successful. In fact, I no longer think of Springs & Struts as just another name for myself — instead, it has become its own thing. I couldn’t be happier.

I’ve also been on a few podcasts. I recently made an appearance on my friend Kanen Flowers’s new podcast, Scruffy Thinking. I was on the episode “I Do All My Writing in Latex” with Kanen, Ron Brinkmann and Merlin Mann (holy shit) talking about Markdown and text documents and text editors and things like that. I think I did a pretty good job of pretending to sound intelligent. Additionally, some clips that were cut from that episode (and other Scruffy Thinking episodes) ended up on “The Real @cbarrett” — including the Dirk Gently–esque story of how Kanen and I met.

You can also hear me on the teasers for the upcoming Postmodem podcast, with my friends Phillip Bowden and Patrick Thomson. It’s a little more free form than Scruffy Thinking, but we discuss things of general interest to nerds — movies, comics, music, tech, and so on. So far we’ve only released a couple of lower quality clips to whet the appetite, but we have a few full episodes in the can waiting on editing. Eventually they’ll see release, and we’re already planning to record more.

Also worth noting is that Nullary Sources, the link blog I co-host with ‘Ili Butterfield, is still going strong. We’ve been posting a lot of great content that’s tough to sum up in one go — instead I recommend just going and checking it out.

And of course I’m on the usual cadre of social networks. I recommend my venerable Twitter account as well as my activity on Quora — a relatively new Q&A service that I’ve really been enjoying lately. I’ve written over 300 answers about a wide variety of subjects.

All of this is my very roundabout way of saying that while I haven’t necessarily been writing as much here as I’d like to, I’ve been putting content out there if you know where to find it.

Comments Off

Staying away from Android

Wednesday, September 7th, 2011

As if there wasn’t already reason enough, Florian Mueller on FOSS Patents drops a bombshell. Maybe the bombshell.

It’s all there — all your worst fears about Android, confirmed by filings for Oracle v. Google. The twofacedness about “open”. Giving preferential treatment to specific OEMs (specifically Motorola).

And this, which I already understood implicitly but it’s still sickening to see it spelled out like this, from a 2009 document entitled “Android Strategy and Partnerships Overview”:

“Android isn’t a new product to monetize; it’s a new medium to drive monetization on existing products.”

Combined, it’s all enough to make me physically ill. I’m staying out of this mess. There’s no way something this gross can be sustainable. And if it somehow does succeed — if Google’s story plays out the same way as Microsoft’s did (which is what all of this really reminds me of) — count me out anyway.

Also posted on Quora.

Comments (2)

Why GNU grep is fast

Monday, August 8th, 2011

Mike Haertel, original author of GNU grep:

#1 trick: GNU grep is fast because it AVOIDS LOOKING AT EVERY INPUT BYTE.

#2 trick: GNU grep is fast because it EXECUTES VERY FEW INSTRUCTIONS FOR EACH BYTE that it *does* look at.

Fantastic knowledge dump. I wasn’t aware of the Boyer-Moore algorithm that GNU grep uses, but it’s definitely being filed away for future use.

Reminds me of this post by Peter Ammon, about optimizing searching in Hex Fiend, which is also worth reading.

(Via Anant Narayanan.)

Comments Off