Moving to new Objective-C literals

July 30, 2012

Last week, I moved one of my projects over to use the new Objective-C literals for NSNumber, NSArray and NSDictionary as well as the new syntax for boxing expressions into NSNumber and NSString objects.  Here are a few comments on how it went.

In a nutshell, the new language features allow code like [NSNumber numberWithInteger:7] to be replaced by a more compact syntax like @7.  The LLVM site has a full description of the new syntax and usage.

Refactoring in Xcode

I ran the ‘Convert To Modern Objective-C Syntax’ refactoring tool in Xcode 4.4 to do the conversion.  There is no option to choose which modern syntax features you wish to adopt before the conversion begins, but in Xcode 4.4, you can choose diff by diff which changes you wish to keep.  Xcode seems to think my Objective-C syntax is already modern enough in other respects, since the only changes the refactoring made was to move to Obj-C literals.

Even if you want to introduce the new literals into your code manually, you might find it interesting to run the refactoring tool just to browse through its proposed changes.  You can cancel the changes rather than apply them, but just by reviewing the proposed diffs, you might see use cases for Obj-C literals that may not have occurred to you.

There were more places than I was expecting where my code creates NSNumber instances from integer expressions and enums.  Also, before running the refactoring tool, it had not occurred to me how often the expression being boxed would just be a single variable holding a scalar value.

So there were numerous places where the updated code did something similar to the following:

NSInteger myValue = 0;
// Do some stuff that changes myValue
[myArray addObject:@(myValue)];

Before doing the conversion on my own code, I definitely underappreciated the power and usefulness of boxed expressions.

Overall, I found the refactoring in Xcode 4.4. to be easy and straightforward.  The Xcode project I converted was a medium-sized Objective-C project using the iOS 5.1 SDK.

A crashing issue to watch out for

There is a potential crashing issue that I ran into that you should be aware of.  In one spot, the code was relying on a nil value terminating the list of arguments to create an array.  So something like:

-useRequiredValue:(id)requiredObj optionalValue:(id)optionalObj {
   NSArray *array = 
         [NSArray arrayWithObjects:requiredObj, optionalObj, nil];
   // Do something useful with array
}

The method +arrayWithObjects: stops processing arguments when it hits the first nil argument.  The code above relies on that fact to create a one-object array when optionalObj is nil, and a two-object array when optionalObj exists.

The conversion changed the array creation to:

NSArray *array = @[requiredObj, optionalObj];

With array literals, relying on a terminating nil does not work.  Behind the scenes, a literal NSArray is created with +arrayWithObjects:count: which requires non-nil values.  So, after converting to Obj-C literals, an exception was thrown whenever the optional argument was nil.

A similar issue arises with dictionaries if you are relying on early nil-termination with +dictionaryWithObjectsAndKeys: and then move to use an NSDictionary literal.

Note that this issue is not flagged by the refactoring tool or the static analyzer, so it is something to watch out for when converting to use Objective-C literals.

To address the issue, the options are either to revert to the previous code or change the code to something else.

I changed the code to something like this:

NSArray *array =
    (optionalObj != nil) ? @[requiredObj, optionalObj] : @[requiredObj];

I decided to stop using the ‘early nil’ approach for a few reasons.  The first is that I know I will be tempted to change that line of code to use a literal array every time I look at it, which will reintroduce the crash.  I could guard against that by adding an emphatic comment explaining the situation, to prevent myself from changing that line of code.  So, everytime I look at the code, I’ll be tempted to convert the line of code, and then have to read about why I can’t convert that line of code.

It seemed more maintainable to move to a different way of doing the same thing.  In addition, the new code is less tricky/clever than the old code and more explicit about what the result will be; no comment is needed.  I am a big fan of well-commented code, but I’m also a fan of code that is obvious enough that the code can clearly speak for itself.

Readability

In most cases, the new literal syntax leads to code that is both more compact and more readable.  In the above example, the new code is not much more compact than the original code, but, the intent is clearer, which I find more readable.  With numbers, @3.6 is more readable and compact than [NSNumber numberWithFloat:3.6].  For arrays and dictionaries, I find that my eyes are not yet parsing literal array and dictionary creation as smoothly as more familiar Objective-C code, but I suspect that will change as I use and see the new constructs more often.

Boxed expressions may cause readability to suffer to some degree.  When you encounter something like @(someVariable), it is ambiguous whether you are creating a number or string.  You need to know the type of the expression to know for certain.  In practice, descriptive variable names should make this less of an issue.

I find the code becomes less readable as the boxed expression inside the parenthesis becomes more complex and when Objective-C literals and boxed expressions are combined and nested.  We are moving from code that had giant billboards of [NSString stringWith…  or [NSNumber numberWith… proclaiming just what is being creating, to code which is definitely more compact, but may also be more difficult to read.  For example:

@{ValueAverage : @((self.currentValue - [self.relatedObject
    currentValue]) / 2), BoundaryValues : @[@(self.maxValue), @(self.minValue)]}

Even after such a short time using the new syntax, I find that on balance, the literals and boxed expressions make for more readable and compact code, with a few cases where readability seems to suffer a bit.  It is also early in the game, in terms of using the new syntax on a day to day basis.  My opinion will continue to evolve as I use the new constructs more.

Backward binary compatibility and a little BOOL wrinkle

The new Objective-C literal functionality is handled in the compiler, so you must be using a recent version of the LLVM compiler to use this syntax.  Since the compiler generates code that uses existing object creation methods, the code you write and compile can run on previous versions of OS X or iOS.

So, even if you are targeting releases of your app on OS versions earlier than OS X 10.8, or iOS 6, you can use the new literals along with the new version of the tools.

I did encounter one wrinkle with BOOL literals.  To enable the compiler to properly deal with @YES and @NO to represent NSNumber BOOL values, two new language keywords were added to the Objective-C headers.

The iOS 5.1 SDK does not include these new keywords.  So, if you are using Xcode 4.4 and the iOS 5.1 SDK, you need to ‘box’ the BOOL values as expressions to compile: @(YES) and @(NO).

The Mountain Lion 10.8 SDK does have the new keywords as will SDKs moving forward, so this is just a minor transitional oddity.

Conclusion

Overall, I think the new Objective-C literals and boxed expressions are an excellent addition to the language.  I found converting to the new syntax using Xcode 4.4 refactoring to be a smooth process.  The only real bump I hit was in code where I was relying on early nil termination of arguments when creating an array.  The other wrinkle I encountered was the need to box BOOL values using Xcode 4.4. and the iOS 5.1 SDK.   I’m looking forward to using these new language features moving forward.


Categories: Mac, Software Development, iOS

The Liki Song on iTunes!

June 8, 2012


Our new single, The Liki Song, is now available on iTunes.

Like a tropical breeze arriving on the shores of a faraway isle, the new single from James Dempsey and the Breakpoints is here—gliding onto the scene just in time for WWDC 2012.

The Liki Song is a fun, breezy tune with Hawaiian style that recounts a brief history of memory management in Cocoa.

Memory management is a topic as old as computer science itself, and Cocoa has had its share of evolution in this fundamental area.

So mix up a Mai Tai, don your Hawaiian shirt, fire up the Allocations instrument, and take a trip down memory lane.

Click to view The Liki Song in iTunes

Categories: Mac, Music, Software Development, iOS

New Breakpoints Single for WWDC 2012

May 31, 2012

UPDATE: The new single is now live on iTunes!

Click to view The Liki Song in iTunes

Over the past few months, a number of people have asked if there would be a new song for WWDC this year, and I found myself wondering the same thing.

Then, driving into the studio one afternoon, a song started to take shape somewhere between Mountain View and Palo Alto.  So, I’m very happy to announce that there will be a new song this year.

The new single is a fun, breezy tune with Hawaiian style—singing it always brings a smile to my face.  Beyond that, I don’t want to give away too much more until folks can hear it for themselves.

LIVE near WWDC 2012

A surfboard with a picture of a hula dancer painted on it
The show venue John Colins already has the Hawaiian spirit for the LIVE near WWDC 2012 show on June 13th.

You can hear the new song, along with old favorites, at what we’re calling James Dempsey and the Breakpoints LIVE near WWDC 2012 on Wednesday, June 12th.

I’ll have final and full show details next week. I’m really looking forward to a fun evening and playing the new song for everyone. Also, thanks to all the folks who have retweeted and passed the word along about the show.

One Night, One Song

Another great event that week is the Looking Back at NeXTSTEP fundraiser for the Cartoon Art Museum.  The sold-out evening will have many luminaries from the NeXTSTEP days in attendance, all for a great cause.

I’m looking forward to attending the event as a sponsor, but I’m particularly excited, as well as honored, to be participating in the event as the special musical guest.

So, amidst the talk of days before NSString and autorelease pools, attendees will hear the public performance debut of the new single, done as a very ‘unplugged’ version.  Thanks to Dr. Michael Johnson for hosting the event, and for including me in the proceedings.

Fun week coming up fast

WWDC week looks like it will be a fun and busy one with the live show, new single, conference sessions, and maybe best of all, meeting new folks and catching up with friends.

I’ll also be taking requests during the week, so feel free to say hello—and no, we don’t know Free Bird. •


Category: Music

Breakpoints Live Show 6/13 in SF! Save the date!

May 14, 2012

Will you be in San Francisco the week of WWDC?

Do you want to enjoy a performance of humorous and informative songs about Apple development technologies?

Have we got a show for you!

Who: James Dempsey and the Breakpoints

When: Wednesday, June 13th, 7:30 PM – 9:00 PM

Where: John Colins LoungeJust two blocks from Moscone West!

How Much? Free Admission! No Cover! Cash Bar.
The show is free, but the drinks you have to pay for.

What: An evening of James Dempsey and the Breakpoints songs performed live, including favorites such as Hold Me, Use Me, Release Me; I Love View; Model View Controller and more.

Anything else? No WWDC Ticket Required!
A great open event for all developers hanging out in SF that week!

Why all the exclamation marks?  Because this is shaping up to be a fun show and I’m very excited about it!  Tell your friends!  Tweet like the wind!

Other things to know:
• There are no tickets for this event.
• Arrive early for best spots.
• The venue is a bar—you must be 21+ years old to attend.
• Limited # of t-shirts available.  Early birds get their size!
• Don’t take ‘cash bar’ literally. Credit cards also accepted.
• Hang out after the show and say hello.
• Follow @jamesdempsey on Twitter for show updates.

Edited 6/5/2012 to include latest show details


Categories: Mac, Music, iOS

Studio Update: Gonna Needa Pasteboard

April 27, 2012

We recorded Gonna Needa Pasteboard, a rockabilly romp through the world of NSPasteboard. Joining me in the studio was John Scalo on guitar—who also played live on the original—and Raleigh Ledet from the AppKit team who sat in on drums.

John Scalo playing electric guitar in the studio
John Scalo rips it up!
Photo by Adam Tow

John has been at Apple for more than 18 years. He got his start in tech support and says the experience gave him a much greater sense of empathy for users and their issues—an experience he recommends for every engineer or designer at some point in their career. Moving to OS X software engineering, his gigs have included parental controls, screen savers, Internet accounts, Stickies, and security. He also plays a mean guitar.

When John was about 12 or 13, he heard Jimi Hendrix for the first time and made his dad show him how to play Purple Haze. And then he got into the Texas blues. One summer, night after night, he’d walk a mile from his home to hear the house band play at the legendary Antone’s Blues Club in Austin. While in college at UT Austin he played in jazz, funk, and jam bands, doing weekly gigs on 6th Street and ‘The Square’ in San Marcos. His funk band Zzyzywuzsky played at the SXSW music festival. These days John’s tastes are more eclectic ranging from bluegrass to Brazilian, jazz, and some Eastern styles—but he sill loves those Texas blues.

Raleigh has been coding for a long while—he wrote his first commercial software for the Apple ][ in high school. He’s been doing Mac development for 14 years, including eight years at Wacom getting down and dirty with Mac tablet drivers and pref panes. A big fan of pressure-sensitive tablets, Raleigh has also written a number of shareware titles including inkBook, a notebook app with handwriting recognition (using Inkwell, one of the best-kept secrets on the Mac).

Raleigh Ledet playing the drums in the studio
Raleigh Ledet—AppKit meets drum kit
Photo by Adam Tow

For the past four years, Raleigh has been a member of the AppKit team, working in a variety of areas such as event handling, scrolling, various controls, and drag and drop. His focus on drag and drop makes him a perfect fit for Gonna Needa Pasteboard, which has an entire verse about it.

When Raleigh started drumming in 5th grade, his snare drum and case almost weighed more than he did. Growing up in south Louisiana, he played drums in numerous Mardi Gras parades. He has also played drums in various contemporary Christian rock groups over the years.

As for me, I’m definitely learning a lot in the studio. It’s a very different experience than performing live. And although I’m aiming to keep the recordings true to the spirit of the live originals, it is fun to be able to go a bit further, such as adding drums on this track. I also learned that drum sets don’t just load, unload and transport themselves. Maybe next time we just add some piccolo.

James Dempsey at the microphone in the studio wearing "I'm cuckoo for Cocoa Apps" t-shirt
I really am cuckoo for Cocoa apps
Photo by Adam Tow

Categories: Mac, Music