Dave Dribin's Blog tag:www.dribin.org,2007-10-11:/dave/blog//1 2011-04-06T02:12:04Z Movable Type Open Source 4.1 My Unit Testing C4[3] Presentation tag:www.dribin.org,2011:/dave/blog//1.435 2011-04-06T02:12:04Z 2011-04-06T02:12:04Z I should have posted this literally years ago. Since I just learned that Keynote can easily publish presentations to iWork.com, I figure I have no excuse. Thus, here’s my C4[3] presentation on unit testing: [Direct Link]... Dave I should have posted this literally years ago. Since I just learned that Keynote can easily publish presentations to iWork.com, I figure I have no excuse. Thus, here’s my C4[3] presentation on unit testing:

[Direct Link]

]]>
Joining Apple tag:www.dribin.org,2010:/dave/blog//1.434 2010-10-01T23:09:19Z 2010-10-01T23:09:19Z Next week, I fly out to Cupertino to start working at Apple as a full time employee. This is a big move for me, as I’ve been working for myself since 2001. But this is truly a once-in-a-lifetime opportunity that... Dave Next week, I fly out to Cupertino to start working at Apple as a full time employee. This is a big move for me, as I’ve been working for myself since 2001. But this is truly a once-in-a-lifetime opportunity that I cannot pass up. As is the case for a lot of people my age, I began my computing experience on an Apple ][ and have been a huge fan of Apple ever since (with a slight defection to Linux in the late 90s and early 00s). Apple-related technology (Mac OS X and iOS) has been my main source of income since around 2006, so in many ways, this is a dream come true. I’m very excited to work with a great team and for a great company.

]]> Because everything needs an FAQ:

What will you be working on?

I’m not sure that I can say, just yet. But it will involve heavy amounts of coding in Objective-C.

So you’re moving to California?

Nope. I’ll be staying right here in Chicago.

Will you still be writing The Road to Code for MacTech Magazine?

Unfortunately, I will be unable to continue writing The Road to Code for MacTech, and I’ve already submitted my last article. It has been an amazing three years, and I am truly grateful to have worked with MacTech.

What about public speaking?

I will also be unavailable for future speaking engagements. I’ve already had to turn down opportunities to speak at Voices that Matter, the MacTech conference, and SecondConf. I’m sure I will be an attendee at a number of the conferences, though, and I plan to stay active in the community as much as possible.

What does this mean for Bit Maki and Textcast?

This is still preliminary and in progress, but Bit Maki Software, Inc., the joint company between Jonathan Rentzsch and I, is in process of being dissolved. I plan to keep Bit Maki, Inc., my contracting company, alive for now, though I will not be doing any more contracting. Textcast will become free and be available from the Bit Maki website.

What’s the future of MAME OS X?

It has been a few years since I’ve been able to dedicate much time towards MAME OS X, and this is the nail in the coffin. I will not be able to contribute to MAME OS X. If anyone want’s to pick up the effort, please let me know. This also goes for most of my other open source software. Truth be told, with the two recent additions to our family, I’m going to be sufficiently distracted for a while, anyways.

]]>
Welcome Lily and Zach Dribin tag:www.dribin.org,2010:/dave/blog//1.433 2010-09-17T03:04:51Z 2010-09-17T03:04:51Z My wife and I recently brought home two new additions to the Ross-Dribin family: Lily and Zach! All four of us are doing great, but everything since then has been a blur.... Dave My wife and I recently brought home two new additions to the Ross-Dribin family: Lily and Zach! All four of us are doing great, but everything since then has been a blur.

spacer

]]>
trigint: An Integer-based Trigonometry Library tag:www.dribin.org,2010:/dave/blog//1.432 2010-08-15T15:06:26Z 2010-08-15T15:06:26Z Back when I was writing the A440 sample code for my iPad Dev Camp presentation, I needed to generate a 440 Hz sine wave. The simplest way to do this is to use the sin() or sinf() standard C library... Dave Back when I was writing the A440 sample code for my iPad Dev Camp presentation, I needed to generate a 440 Hz sine wave. The simplest way to do this is to use the sin() or sinf() standard C library functions. But there was one minor caveat: these functions required using floating point data types. However, floating point on the iPhone hardware is (or at least was) not that fast compared to integer calculations, especially when compiled in Thumb mode, which is the default. You could disable Thumb mode, but then the code size would be ~35% larger.

Or, you could avoid floating point altogether. Thus, I wrote trigint, a 100% integer-based trigonometry library. It uses a 16-entry lookup table plus linear interpolation so it’s quite memory efficient, yet still accurate enough for most purposes. Since it’s written in ANSI C99, it can be used on 8-bit microcontrollers, like an Atmel AVR with avr-gcc. Here’s the code and the API documentation.

How fast is it? Take a look at the numbers on a 1st generation iPod Touch. In summary, trigint_sin16() is about 4.4 times faster than sinf() and 6.7 times faster than sin() in Thumb mode. Without Thumb mode, the gap closes a bit to 3.8 times faster and 6.2 times faster, respectively. I haven’t, yet run the benchmark on the iPhone 4 or the iPad, so it may not matter as much on the more modern hardware; however, it’s still useful for the the 8-bit MCUs like the AVR, though.

trigint is essentially a C version of the Scott Dattalo’s sine wave routine for the PIC microcontroller. Credit goes to Scott for coming up with the algorithm. He’s also got a whole write up of sine wave theory. Scott is one of the most brilliant assembly coders I’ve ever run into. He helped me optimize a CRC-16 routine in PIC assembly, years ago.

]]>
My Chiptune Cover of Don't Stop Believin' tag:www.dribin.org,2010:/dave/blog//1.431 2010-07-18T14:27:17Z 2010-07-18T14:27:17Z Here’s a chiptune cover of Journey’s Don’t Stop Believin’ I made during some time off I had last December. I just haven’t gotten around to posting it until now (though I did make a few tweaks yesterday). I think we... Dave Here’s a chiptune cover of Journey’s Don’t Stop Believin’ I made during some time off I had last December. I just haven’t gotten around to posting it until now (though I did make a few tweaks yesterday). I think we were watching Glee at the time and remember thinking a chiptune version would be even better than theirs. It was made with FamiTracker, and this video is of the song being played in FamiTracker:

You can listen to and download the MP3 from its 8bitcollective page. Or download the NSF (what’s an NSF?) and play it in an NSF player, such as my own Chip Player. Or perhaps something a bit more stable like Audio Overload.

]]>
Fun with C99 Syntax tag:www.dribin.org,2010:/dave/blog//1.430 2010-05-15T13:52:20Z 2010-05-15T13:52:20Z The C99 language added some pretty neat features to the ANSI C we know and love (now known as C89). I used a construct called compound literals in my iPad Dev Camp presentation, and it seemed new to a lot... Dave The C99 language added some pretty neat features to the ANSI C we know and love (now known as C89). I used a construct called compound literals in my iPad Dev Camp presentation, and it seemed new to a lot of people. Here’s a summary of some lesser know features about C99 that are worth knowing. And, since Objective-C is a strict superset of C, all this applies to Objective-C, as well. Best of all, as of recent Xcode (3.0? 3.1?), C99 is the default C dialect for new projects, so you don’t need to do anything to start taking advantage of these.

]]> Structure Initialization

Structure initialization received a lot of love in C99. In C89, you could initialize a structure variable like this:

NSPoint point = {0, 0};

The caveat here is that the structure elements must be provided in the order that they are listed in the definition. In this case, NSPoint is declared as like:

typedef struct _NSPoint {
    CGFloat x;
    CGFloat y;
} NSPoint;

So, when we initialize a variable, x comes first, followed by y. This can be a drawback because if the order in the definition ever changed, all existing code that depended on the order would break. As of C99, you can initialize a structure by specifying the structure element names:

NSPoint point = { .x = 0, .y = 0};

This not only decouples the order of the definition from the order of the initialization, but it’s more readable. As an added benefit, any structure elements not initialized are set to zero. This means you only need to fill out the portions of the structure that are relevant. And if new elements to the structure are added in later versions, they get initialized to a known value.

The benefit of this becomes even more clear for nested structures like NSRect:

typedef struct _NSRect {
    NSPoint origin;
    NSSize size;
} NSRect;

To initialize an NSRect in straight C89 looked something like this:

NSRect rect = {{0, 0}, {640, 480}};

Because this is kind of awkward, there’s a function to make this a bit easier:

NSRect rect = NSMakeRect(0, 0, 640, 480);

But, honestly, that’s not much of an improvement in readability. NSMakeRect is more useful in structure assignment, but we’ll see an alternate way to do this below. With C99, we can initialize this variable like:

NSRect rect = {
    .origin.x = 0,
    .origin.y = 0,
    .size.width = 640,
    .size.height = 480,
};

Again, we can order the structure elements however we please; we’re not required to list them in the order of the definition. We have some flexibility in how we assign the nested structures, too. This is also legal:

NSRect rect = {
    .origin = {.x = 0, .y = 0},
    .size = {.width = 640, .height = 480},
};

As as this:

NSRect rect = {
    .origin = NSMakePoint(0, 0),
    .size = NSMakeSize(640, 480),
};

And even this:

NSRect rect = {
    .origin = otherRect.origin,
    .size = NSMakeSize(640, 480),
};

So, as you can see, we get a lot more flexibility on how to initialize structures.

Compound Literals for Structure Assignment

This new syntax of initializing structure variables is great, but it doesn’t help us much for assigning to existing structure variables. The example I used in my iPad Dev Camp talk was setting up a AudioStreamBasicDescription structure, colloquially known as ASBD. This structure is used to describe an audio format for Core Audio. In this case, I had an ASBD instance variable. Because it’s an instance variable, you cannot set its value using the initialization syntax above. Thus, the traditional way to initialize one of these it to clear out it to zero with memset, and then set the fields you need, one by one:

memset(&_dataFormat, 0, sizeof(_dataFormat));
_dataFormat.mFormatID = kAudioFormatLinearPCM;
_dataFormat.mSampleRate = SAMPLE_RATE;
_dataFormat.mBitsPerChannel = 16;
// And on and on...

Using new C99 syntax known as a compound literal, you can set an existing structure variable like this:

_dataFormat = (AudioStreamBasicDescription) {
    .mFormatID = kAudioFormatLinearPCM,
    .mSampleRate = SAMPLE_RATE,
    .mBitsPerChannel = 16,
    // And on and on...
};

It looks similar to a cast plus an initialization. And under the hood, the compiler is making a anonymous variable. So you can think of the above as equivalent to:

AudioStreamBasicDescription anon = {
    .mFormatID = kAudioFormatLinearPCM,
    .mSampleRate = SAMPLE_RATE,
    .mBitsPerChannel = 16,
    // And on and on...
};
_dataFormat = anon;

Again, the nice thing here as that unset fields are initialized to zero, so you get the equivalent of the memset. Plus, you don’t have to repeat the variable name over and over again.

Oh, and as a quick shorthand for setting the entire structure to zero, you can do something like this:

_dataFormat = (AudioStreamBasicDescription) {0};

Compound Literals with Primitives

Compound literals can be applied to primitive types, too. Most of the time this is not much use:

int i = (int) {3};

But because these are anonymous variables, you can take the address of them:

int * iPointer = &(int) {3};

This can be useful for some Core Audio APIs, such as AudioUnitSetProperty. Typically you create a variable for the sole purpose of taking the address of it:

UInt32 maxFramesPerSlice = 4096;
AudioUnitSetProperty(converterAudioUnit,
                     kAudioUnitProperty_MaximumFramesPerSlice,
                     kAudioUnitScope_Global,
                     0,
                     &maxFramesPerSlice,
                     sizeof(UInt32));

Using compound literals, we can do this inline without an extra variable:

AudioUnitSetProperty(converterAudioUnit,
                     kAudioUnitProperty_MaximumFramesPerSlice,
                     kAudioUnitScope_Global,
                     0,
                     &(UInt32) {4096},
                     sizeof(UInt32));

Conclusion

While C99 was a relatively minor update to C89, there are quite a few gems buried away to make our code more flexible and readable, as you can see.

]]>
iPad Dev Camp Slides tag:www.dribin.org,2010:/dave/blog//1.429 2010-05-03T04:11:00Z 2010-05-03T04:11:00Z First off, a big thanks to David Kinney (@dlkinney) for organizing this year’s iPad Dev Camp Chicago. Here are the slides to my Core Audio presentations: Audio Queue Services Audio Unit Graphs The source code to the two projects I... Dave First off, a big thanks to David Kinney (@dlkinney) for organizing this year’s iPad Dev Camp Chicago. Here are the slides to my Core Audio presentations:

  • Audio Queue Services
  • Audio Unit Graphs

The source code to the two projects I went over are up on BitBucket:

  • A440: A Core Audio “Hello World”. Runs on Mac, iPhone, and iPad.
  • Chip Player: A chiptune player using the Game Music Emu library. Runs on Mac and iPad and plays popular chiptune file formats, such as NSF and GBS.

Use the ipaddevcamp2010 tag to see what they looked like at the time of the presentations.

]]>
A440: A Core Audio "Hello World" tag:www.dribin.org,2010:/dave/blog//1.428 2010-04-26T14:00:49Z 2010-04-26T14:00:49Z iPad Dev Camp Chicago is coming up this weekend, and I’m going to be giving two talks about Core Audio. One of the applications we are going to go over is called A440, a “Hello World” of Core Audio. It... Dave iPad Dev Camp Chicago is coming up this weekend, and I’m going to be giving two talks about Core Audio. One of the applications we are going to go over is called A440, a “Hello World” of Core Audio. It plays a simple a 440 Hz tone using both Audio Queue Services (AudioQueueRef and friends) and Audio Unit Processing Graph Services (AUGraph and friends). In order to keep the code as simple as possible, it does not use any of the “Public Utility” C++ APIs.

I’ve posted the code up on BitBucket if you want to check it out before hand or are unable to attend. I also hope to have a more complex and complete audio playing application ready to release by this weekend, too. Hint, it’ll have something to do with 8-bit chiptunes. So if you’re in Chicago, sign up! It’ll be fun!

]]>
Debugging Asynchronous performSelector: Calls tag:www.dribin.org,2010:/dave/blog//1.427 2010-03-20T04:42:49Z 2010-03-20T04:42:49Z This afternoon, I had to debug an issue that involved performSelectorOnMainThread:. This method is a great way to get a background thread to safely interact with the user interface. But when you set a breakpoint or crash nested down in... Dave This afternoon, I had to debug an issue that involved performSelectorOnMainThread:. This method is a great way to get a background thread to safely interact with the user interface. But when you set a breakpoint or crash nested down in one of these method calls, sometimes it’s useful to get a backtrace of who called performSelectorOnMainThread:. Unfortunately, by the time our method gets called, we don’t have that information. The same goes for performSelector:withObject:afterDelay:.

After some good suggestions on Twitter, and a bit of casual recreational coding, I’ve come up with a general purpose solution that involves, of course, method swizzling.

]]> Take this code in an application delegate as an example:

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        [self performSelectorOnMainThread:@selector(echo:) withObject:@"foo" waitUntilDone:NO];
    });

    [self performSelector:@selector(echo:) withObject:@"bar" afterDelay:3.0];
}

- (void)echo:(id)object
{
    NSLog(@"echo: %@", object);
}

If you set a breakpoint in the echo: method, you’ll see a backtrace like:

(gdb) bt
#0  -[PerformDebugAppDelegate echo:] (self=0x10012c480, _cmd=0x100002462, object=0x1000030e8) at /Users/dave/Desktop/PerformDebug/PerformDebugAppDelegate.m:42
#1  0x00007fff83500647 in __NSThreadPerformPerform ()
#2  0x00007fff80477271 in __CFRunLoopDoSources0 ()
#3  0x00007fff80475469 in __CFRunLoopRun ()
#4  0x00007fff80474c2f in CFRunLoopRunSpecific ()
#5  0x00007fff8101ea4e in RunCurrentEventLoopInMode ()
#6  0x00007fff8101e7b1 in ReceiveNextEventCommon ()
#7  0x00007fff8101e70c in BlockUntilNextEventMatchingListInMode ()
#8  0x00007fff870b21f2 in _DPSNextEvent ()
#9  0x00007fff870b1b41 in -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] ()
#10 0x00007fff87077747 in -[NSApplication run] ()
#11 0x00007fff87070468 in NSApplicationMain ()
#12 0x0000000100001a09 in main (argc=1, argv=0x7fff5fbff1f0) at /Users/dave/Desktop/PerformDebug/main.m:29

This really isn’t all that helpful. Yes, echo: was called, but we don’t know who called it. If echo: is a method that tends to get called from a number of places with a performSelector... variant, we don’t know which one it is.

This afternoon, I took the easy way out, and set an auto-continuing breakpoint on -[NSObject performSelector:onThread:withObject:waitUntilDone:modes:] with a bt action. This isn’t ideal, though. First, this method gets called quite a bit, so hitting the breakpoint can slow things down a lot. Plus, it dumps the stack trace for each call, cluttering the gdb console with mostly useless garbage.

The breakpoint actually helped me debug the issue today, but I’ve run into this situation a number of times in the past and never had a good way to debug it. Until now.

Swizzling for Fun and Profit

The key is to swizzle the NSObject implementations of these two methods:

  • performSelector:withObject:afterDelay:inModes:
  • performSelector:onThread:withObject:waitUntilDone:modes:

In our swizzled implementations, we’d like to capture the backtrace at time they are called. Later, we can dump out the backtrace for debugging, if we want to. To do this, we’ll create an intermediate object to hold the backtrace: DDPerformDebugger. Here are its two most important methods:

- (id)initWithTarget:(id)target selector:(SEL)selector argument:(id)argument;
{
    self = [super init];
    if (self == nil)
        return nil;

    _target = [target retain];
    _selector = selector;
    _argument = [argument retain];
    // Capture a backtrace at the time we're created
    _frames = backtrace(_callstack, sizeof(_callstack)/sizeof(*_callstack));

    return self;
}

- (void)perform;
{
    [_target performSelector:_selector withObject:_argument];
}

In the initializer, we capture the target, selector, and argument. But we also capture a backtrace using the very handy backtrace(3) function.

In our swizzled performSelector..., we create an instance of DDPerformDebugger, but instead of passing the target and selector to the original implementation, we use this instance as the target and perform as the selector. As you can see above, this just forwards it on to the passed in target and selector. However, as I demonstrate below, we’ll have access to the saved backtrace. Here’s what the swizzled method looks like:

- (void)dd_performSelector:(SEL)selector withObject:(id)argument afterDelay:(NSTimeInterval)delay inModes:(NSArray *)modes;
{
    DDPerformDebugger * debugger = [[DDPerformDebugger alloc] initWithTarget:self
                                                                    selector:selector
                                                                    argument:argument];
    [debugger autorelease];

    // This calls the original implementation.  It's not recursing.
    [debugger dd_performSelector:@selector(perform)
                      withObject:nil
                      afterDelay:delay
                         inModes:modes];
}

The swizzled dd_performSelectorOnMainThread:... looks similar. Now, when we stop on our breakpoint in echo:, we get the following backtrace:

(gdb) bt 5
#0  -[PerformDebugAppDelegate echo:] (self=0x10012b170, _cmd=0x100002462, object=0x1000030e8) at /Users/dave/Desktop/PerformDebug/PerformDebugAppDelegate.m:42
#1  0x000000010000207c in -[DDPerformDebugger perform] (self=0x10101ae00, _cmd=0x7fff85a42a1a) at /Users/dave/Desktop/PerformDebug/DDPerformDebugger.m:157
#2  0x00007fff83500647 in __NSThreadPerformPerform ()
#3  0x00007fff80477271 in __CFRunLoopDoSources0 ()
#4  0x00007fff80475469 in __CFRunLoopRun ()
(More stack frames follow...)

This isn’t much help on it’s own. But if we jump to frame 1, where we’re inside the perform method of our intermediate object, we have access to the backtrace of the original calling point. I’ve rigged up the description method to show the backtrace, so it’s easy to get:

(gdb) po self
<DDPerformDebugger 0x10101ae00: target: <PerformDebugAppDelegate 0x10012b170>, selector: <echo:>, argument: <NSCFString 0x1000030e8>
0   PerformDebug                        0x0000000100001f45 -[DDPerformDebugger initWithTarget:selector:argument:] + 268
1   PerformDebug                        0x0000000100001d3c -[NSObject(DDPerformDebugger) dd_performSelector:onThread:withObject:waitUntilDone:modes:] + 99
2   Foundation                          0x00007fff83512d54 -[NSObject(NSThreadPerformAdditions) performSelectorOnMainThread:withObject:waitUntilDone:] + 143
3   PerformDebug                        0x0000000100001b42 __-[PerformDebugAppDelegate applicationDidFinishLaunching:]_block_invoke_1 + 66
4   libSystem.B.dylib                   0x00007fff86eebce8 _dispatch_call_block_and_release + 15
5   libSystem.B.dylib                   0x00007fff86eca279 _dispatch_worker_thread2 + 231
6   libSystem.B.dylib                   0x00007fff86ec9bb8 _pthread_wqthread + 353
7   libSystem.B.dylib                   0x00007fff86ec9a55 start_wqthread + 13

We can see we’re on on a GCD thread inside applicationDidFinishLaunching:. The only downside to the backtrace_symbols(3) function is that it does not utilize debugging information to show line numbers. We just get an offset into the method.

Fortunately, a command line tool called atos(1) can provide us with this information. Given an address, it’ll decode the symbol and line number information. We can even invoke this right from inside gdb:

(gdb) info pid
Inferior has process ID 11017.
(gdb) shell atos -p 11017 0x0000000100001b42
__-[PerformDebugAppDelegate applicationDidFinishLaunching:]_block_invoke_1 (in PerformDebug) (PerformDebugAppDelegate.m:35)

And know we know that performSelectorOnMainThread: was originally called from line 35 of PerformDebugAppDelegate.m. Very helpul!

The full code for DDPerformDebugger is part of my DDFoundation project on BitBucket, but you can grab just the one file on its own and and included it with your project. By default, it does not swizzle anything, so you can compile it in for every build and not worry about taking a performance hit creating those intermediate objects. To enable the swizzling, just set the DDPerformDebug environment variable to YES. Grab a sample project, PerformDebug.tgz, and try it out for yourself.

]]>
What I Miss from Java tag:www.dribin.org,2010:/dave/blog//1.426 2010-03-02T15:28:01Z 2010-03-02T15:28:01Z On Monday, I had a series of tweets ([1], [2], [3]) about what I like about Java that I miss in Objective-C/Cocoa that were probably better off in a blog post. I blame Jeff LaMarche for baiting me into the... Dave On Monday, I had a series of tweets ([1], [2], [3]) about what I like about Java that I miss in Objective-C/Cocoa that were probably better off in a blog post. I blame Jeff LaMarche for baiting me into the tweet rant, so here’s the the same thing, in blog post format with more detail and other points I forgot to mention.

What I Miss

Before settling in on Objective-C, I was a Java guy for about six years or so. Overall, I much, much prefer coding in Objective-C to Java, and have no intentions of going back to Java. But that doesn’t mean there’s some things I miss. Here’s a quick list, with more detail below:

  • A flexible I/O class hierarchy
  • Everything in java.util.concurrent
  • Exceptions for errors
  • Packages, a.k.a namespaces
  • One file for interface/implementation
  • Type safe enum classes
  • Annotations
  • Awesome IDEs (IntelliJ)
]]> A Flexible I/O Class Hierarchy

Overall, I feel the java.io package is really well designed. I like the difference between InputStream/OutputStream that are byte-oriented and Reader/Writer that are text-oriented. Also, there’s some cool subclasses such as GZIPInputStream, GZIPOutputStream, and LineNumberReader

Java’s InputStream and OutputStream are easier to subclass than NSInputStream and NSOutputStream since there’s fewer methods to deal with. Plus, there’s a lingering bug in NSInputStream that makes it effectively impossible to subclass in some really handy situations. See this mailing list post from 2007 that mentions rdar://problem/322278.

Everything in java.util.concurrent

Ever since I read Java Concurrency in Practice, I’ve been drooling over a lot of stuff Java programmers have available in their arsenal in java.util.concurrent. The Executor is roughly equivalent to a Grand Central Dispatch queue and theExecutorService is roughly equivalent to an NSOperationQueue, but that’s where the similarities end. Granted, I think the Cocoa and GCD APIs are more palatable, especially since the introduction of blocks, but there’s a bunch of classes we don’t have that would have been really useful at some point or another:

  • BlockingQueue and it’s implementations are handy for passing objects between threads. The need for this is partially mitigated by GCD, but it’d still be nice to have these to feed objects from one queue to another.
  • ConcurrentHashMapis an awesome, thread safe and scalable map/dictionary.
  • CopyOnWriteArrayList and CopyOnWriteArraySet are really nice for mostly read-only data.
  • The atomic classes in java.util.concurrent.atomic are nicer than dealing with the OSAtomic functions.
  • The Future interface has some very handy uses. Mike Ash just wrote a blog post on futures in Objective-C, but I think I prefer explicit futures to implicit futures.
  • The SwingWorker class offers nice integration of asynchronous background tasks with the user interface thread. I’ve used a similar pattern in Objective-C, but I think it’d be nice to have this encapsulated in a reusable object.
  • The java.util.concurrent.locks package has some nice specialty locks such as ReentrantReadWriteLock.

Exceptions for Errors

Objective-C may have exceptions, but they are only used for programming errors or essentially fatal runtime errors. Error handling is done with NSError. This is different than Java, which uses exceptions for expected error cases, such as error reading from a file, or failure to execute a database transaction. This isn’t just a Java thing. Most modern languages like Python, Ruby, and C# use exceptions as Java does. Not using exceptions as error handling was one of the harder habits for me to break; however, I’ve come to embrace NSError and eschew exceptions in Objective-C, even if I don’t like it.

I’ve debated this a number of times with people, but having dealt with both exceptions and NSError, I still prefer exceptions. The big argument against exceptions is that they are non-local jumps causing confusing behavior and subtle bugs. I guess I’ve never seen this happen. Plus there’s also the fact that Foundation and AppKit are not exception safe, so throwing exceptions through these frameworks can and will lead to memory leaks and probably unpredictable behavior. Thus, the best course of action to handle an exception is to gracefully terminate the app.

To me, NSError doesn’t result in more robust code than exceptions. 90% of the time, people just pass NULL or log the NSError in place instead of passing it up to where it’s better handled. A big reason for this is that NSError is returned as an output parameter. Thus to pass an NSError up to a higher level requires that an NSError be added to every method up the chain. Not only is this ungainly, but it’s sometimes not possible to add an NSError to an existing API. This is also a problem with checked exceptions Java, which is why most Java people endorse unchecked exceptions these days.

Exceptions really shine when you call multiple methods in a row that can fail. In Objective-C, your best bet is to return early or use a goto. This still litters your code with error handling that drowns out the real code. With exceptions, the error handling code is nicely separated from the “happy” code path. Perhaps exceptions aren’t the be-all end-all of error handling, as I’ve recently been intrigued by the error handling of Haskell. However, this is not something we’ll see in Objective-C any time soon.

Packages, a.k.a Namespaces

Classes in Objective-C live in a big, flat, global namespace. The common workaround is to prefix class names with two or three letters. Thus, I’d name my classes DDObject or some such. The problem with this approach is that two or three letters is just not enough of a namespace. It helps reduce collisions, but it does not eliminate them. Plus, Apple no longer uses only the NS prefix. It uses CA, CI, CV, QC, AB, UI, PS, IO, QL and probably more. A safe prefix today may be a collision tomorrow.

Things get even more dire when it comes to categories. Category smashing happens, and it’s hard to debug. The only way to avoid it is to prefix your category methods with some unique prefix, as well.

Packages or namespace could theoretically solve both of these collisions. This is not an unknown issue. Many radars have been filed, such as rdar://problem/7025435, that are all duped to a very low radar: rdar://problem/2821039. The problem is this isn’t an easy thing to bolt onto an existing language, because, of course, we want it done in a backwards compatible manner that doesn’t impact the performance of objc_msgSend(). So I understand why we don’t have it, but that doesn’t mean I don’t want it.

One File for Interface and Implementation

There are some good things about the separate of the interface in the .h file and the implementation in the .m file. However, I really despise having to keep these two up-to-date. Many accumulated hours have been lost to compile warnings and errors due to updating one without the other. The repeated method definitions are very un-DRY.

Others suggested that they like this separation of interface from implementation details, only exposing what’s necessary to users of the class, and conceptually I agree. In practice, I find it a chore. Perhaps the repeated code could be mitigated with some Xcode assistance. For example, add a method in the .m and it offers to add it to the .h for you. I think I could deal with this.

However, some of the private details are still exposed in the headers, namely the instance variables. The modern Objective-C runtime, available in 64-bit on Mac OS X and the native iPhone environments, allow synthesized ivars, meaning you can declare properties, and the

gipoco.com is neither affiliated with the authors of this page nor responsible for its contents. This is a safe-cache copy of the original web site.