Initialize

Back when I did all my work in C, I got into the habit of always initializing any variable I declared at the time of declaration, like this:

char * myStr = NULL;

That way I could be assured that the variable in question had a known value stored in it at runtime. It may be the wrong value, if I did not subsequently set the value to whatever it was supposed to become, but it made my life as a programmer a little more predictable, and often a little less crashy.

Then I became a Cocoa developer, and learned that the Objective-C runtime initializes ivars to 0 for objects. This was extremely useful behavior when combined with another special rule of the runtime, which was that messaging nil was a no-op, and always returned 0 (unless you were assigning the return value to a struct, in which case it was garbage, but as of very recently, clang has changed that to return 0‘ed memory as well!). This meant that you could create a new class with a bunch of ivars and you didn’t have to initialize each one manually in the initializer in order to start an object’s lifetime with a reasonable set of defaults that wouldn’t cause your program to crash under most circumstances. Compared to equivalent default operations in C and C++, ObjC initializers could be shorter or nonexistent, and code was safer by default. Under most circumstances, Objective-C has your back.

Objective-C - or rather Cocoa, I suppose - has another initialization idiom. It’s related to NSError** out arguments in method signatures. Cocoa APIs don’t do a whole lot of error handling. It’s not like an environment like Java where methods declare that they throw exceptions all over the place, and code is teeming with try/catch statements. On the relatively few occasions that an API method needs to pass error-related information back to the caller, the convention is for the return value of the method to indicate success, and for detailed error information, if any, to be returned via an NSError** out parameter. So to make this concrete, the signature for a method that indicates failure and provides enhanced error information might look like this:

- (BOOL)doSomethingThatMightFail:(NSError **)error;

And it would be called like this:

NSError * error;
if (![obj doSomethingThatMightFail:&error]) {
   NSLog(@"Stuff didn't work.  Here's the error:[%@]", error);
}

Notice anything weird about that code? That’s right: I didn’t initialize the error variable. But the convention for methods like this in Cocoa is to NOT initialize the error variable, and to only check the value of the error variable in the event that the return value of the method indicates failure. When the method fails, it is guaranteed to have filled in the error variable with some kind of truly fascinating NSError-ry goodness. And when the method succeeds, it is guaranteed to have left the error value unmolested.

So guaranteed are these guarantees that Apple’s documentation of NSError handling (I swear this was true the last time I checked) specifically indicated that you needn’t bother to initialize the error variable, and example code left it uninitialized. Of course, when I checked the documentation today I couldn’t find where it specifically said you shouldn’t bother to initialize the error variable, but some of the example code still shows the idiom . Bill Bumgarner also tends to make it clear to folks on stackoverflow.com that initializing the error variable is unnecessary. And indeed upon learning the idiom I, as an orthodox Cocoa developer, took to it as well.

I’ve written a lot of code that doesn’t initialize the error variable, and it all has worked out swimmingly for me. Until today. Today I was happily not initializing my error variable when I hit a crash. A crash? That’s not like me! (Yes it is!) Here was the code, essentially:

NSError * error;
BOOL success = [obj doSomethingThatMightFail:&error];
dispatch_async(dispatch_get_main_queue(), ^{
    if (!success) {
        NSLog(@"You got an error:[%@]", error);
    }
});

The example doesn’t make clear why I needed to handle my error on the main queue, but trust me, I did. Boy, did I ever. Anywho, when I ran this code I saw a crash inside dispatch_async(). Block_copy_helper() was on the stack, and it had crashed inside -retain. That was odd. None of my code was on the stack after the call to dispatch_async(). So the problem was a result of an action taken by dispatch_async(), but I was setting it up to crash somehow.

One thing we know about dispatch_async() is that it needs to run the block we give it after the stack on which the block was declared has gone away. In order to do that, it must copy the block onto the heap, hence the call to Block_copy_helper(). And if the block has to be referenced after the stack has disappeared, it stands to reason that any objects it contains references to must also be live after the stack has disappeared. And the only way to guarantee that is to retain those objects.

So that explains how we got the point there a call to -retain inside Block_copy_helper() was crashing. One of the objects being retained was bad. In the code above it’s readily apparent which object that must be, since my block only references one object: error. Earlier today, it wasn’t so clear. But I figured it out anyway because, well, because I had to. My mom wasn’t going to. She was busy.

The answer to this mystery is, of course, that the error variable was not initialized, and that Block_copy_helper() was trying to retain it while it was copying the block. Normally, because of the idiom I described above it would be perfectly fine to leave the error variable uninitialized. In fact, if you initialized it and showed it to someone who worked at Apple, chances would be good that they would specifically tell you that you didn’t need to initialize it. But in this case, my deadened C programmer instincts would have steered me right, had I listened to them. Initializing the error variable to nil, as follows, fixed the crash:

NSError * error = nil;
BOOL success = [obj doSomethingThatMightFail:&error];
dispatch_async(dispatch_get_main_queue(), ^{
    if (!success) {
        NSLog(@"You got an error:[%@]", error);
    }
});

To summarize, you just read a really long explanation that could have been stated more succinctly as, “Always initialize your object variables to nil, no matter what, because some day they may be captured by a block and if they contain junk when the block is copied you’re going to crash.” And you will never get that time back.

ADDENDUM

It has been pointed out to me by some folks via Twitter (specifically @bbum and @drance) that my solution is not solutiony-enough. Specifically, they point out that I was wrong regarding the convention of how the error variable is treated by the callee on success. As I stated above, I thought that on a successful call the error variable would remain untouched, but that is apparently not part of the agreement. On success, error may, in fact, have been used as scratch memory by the callee and left full of garbage (rude!). In that case, the capture of the error variable by the block below will result in yet another crash.

So there are a couple of better solutions. One is to assign nil to the error variable on success, to guard against it being full of garbage when captured by the block, like so:

NSError * error;
BOOL success = [obj doSomethingThatMightFail:&error];
if (success) {
    error = nil;
}
dispatch_async(dispatch_get_main_queue(), ^{
    if (!success) {
        NSLog(@"You got an error:[%@]", error);
    }
});

Another solution would be to dispatch a different block for handling the error case than to handle the success case, so that in the success case the block doesn’t have to capture the potentially-dangerous error variable:

NSError * error;
if ([obj doSomethingThatMightFail:&error]) {
    dispatch_async(dispatch_get_main_queue(), ^{
        // Handle success here, without referencing the error variable
        NSLog(@"success...");
    });
}
else {
    dispatch_async(dispatch_get_main_queue(), ^{
        // Handle the error here, where we are guaranteed to have a good value for error.
        NSLog(@"You done wrong:[%@]", error);
    });
}

Depending on what you need, I think both approaches have their merits. And both are better than what I wrote above, because they prevent crashes in the event that -doSomethingThatMightFail: leaves junk in error.

I should also note, as was noted to me via Twitter by some other people (@olebegemann and @jonsterling), that if I had just seen the light and compiled under ARC, we wouldn’t be having this discussion because ARC initializes local object variables to nil. Which is, of course, awesome. But sadly my project isn’t in a place where it is ready for that step right now. Soon!

My humble appreciation to all who endeavored to steer this blog post to a better landing. To re-summarize, I guess I would say “Compile under ARC. But if you can’t do that, it’s up to you to ensure your error variable isn’t full of junk when you reference it later on.” Hm, that’s a less-grandiose lesson to be learned, but at least it will actually work. Thanks!

ADDENDUMDUM

The note above regarding ARC is incomplete. ARC will set error to nil for us, but that doesn’t make any difference regarding the behavior of the -doSomethingThatMightFail: method. That method may still put things into error on success. If I’m understanding this right, an object stored into error under ARC should be safe to copy and reference, though, at least from a memory management standpoint.

But the point still stands that if your block captures the error variable on success, you may have an object going along for the ride that you did not expect to. So the two techniques given just above for ensuring you don’t have unexpected values in error should still be used, even under ARC. Thanks again to @bbum and @drance for bringing this to my attention! And please let me know if I still have this wrong. You can reach me via Twitter as @ryfar.

Team Lunch

Joel Spolsky has a piece on eating lunch with your team. As usual, he demonstrates wisdom and intelligence.

The teams with which I have been most successful have been teams that ate lunch together. Eating lunch together means an opportunity for unstructured conversation. Unstructured conversation may include:

  • Jokes about each other
  • Jokes about other teams
  • Jokes about each other’s moms
  • Serious conversations regarding video games
  • Relations of lessons hard-learned

Four of the five items in the list above are beneficial to both group cohesiveness and individual knowledge and productivity. Can you guess which four?

Trick question; the correct answer is all five.

Functional Banana vs. Stateful Gorilla

John D. Cook’s post quotes Joe Armstrong, creator of Erlang, on software reusability. This goes along well with the Law of Demeter. The goal of the Law of Demeter is to reduce the coupling between object-oriented code modules, thus decreasing the side-effects of your code – the size of the gorilla holding that banana you’d like to use.

In application development, we end up needing to manage a lot of state. The key is to minimize the state we’re managing and the coupling between modules, and to recognize when it makes sense to factor our code into functional chunks that are free of state and side-effects. The benefit we gain is code that is easier to understand, debug, and reuse.

"Only talk to your friends."

The Law of Demeter is a definitive starting point for API design. But it’s also a great guideline for designing every layer of code, including your private classes and functions. This link points to Karl Lieberherr’s landing page for the Law of Demeter, but Wikipedia may have a more accessible description.

The fundamental concept of the Law of Demeter is that a class should only talk to its friends. That is, don’t do this:

[memberObject.somethingThisObjectKnowsAbout changeSomething:newValue];

Instead, do this:

[memberObject changeSomethingThisObjectKnowsAbout:newValue];

Why? What does this get you? What it gets you is reduced fragility of your class. That is, since the details of memberObject’s implementation are not of concern to your class, memberObject can change its implementation freely without affecting your class. In fact, memberObject can get rid of its somethingThisObjectKnowsAbout member entirely, and as long as its interface stays the same, your class won’t know the difference. It will blissfully continue to work properly with no changes.

The alternative is for you to have to change your class’s implementation when the implementation of memberObject changes. When memberObject decides to replace somethingThisObjectKnowsAbout with two different objects doing the job somethingThisObjectKnowsAbout used to do, you’ll need to change your class to talk to the right one. And changing code that shouldn’t need to change makes baby Jesus sad.