Go ahead and use Core Data

In a few weeks, it will be **four years** since Mac OS X 10.4 Tiger was first released. That was the first release to include Core Data. It will also be about **one and a half years** since Mac OS X 10.5 Leopard was released, with significant enhancements to the Core Data API.

It’s pretty safe to start using Core Data in your applications now. You certainly don’t need to wrote directly to the low-level SQLite API any more.

DDJ vs. Backyard Poultry

Eric Sink has a post talking about the sad state of developer publishing, specifically discussing the declining readership of the venerable developer magazine Dr. Dobb’s Journal, as compared to that mainstay of American newsstands Backyard Poultry.

After reading the article and the replies, I just had to throw in my two cents about magazine publishing and why “1% of the US population are software developers, so there should be a huge market for development magazines.”

It’s a significant mistake to think that the reader is the target and that the magazine is the product.

It is actually the aggregate readership that is the product, and the advertisers who are the target. That is, unless the magazine takes no advertising and is entirely supported by its subscribers.

This was driven home to me recently when I bought the recent “eInk Flashing Cover” issue of Esquire. I had never read Esquire before, so in addition to checking out the cool hardware on the cover, I started trying to read it. It was way more full of ads than Wired ever was — even in the days when Suck famously disassembled Wired 3.09 to remove the ads.

Furthermore, its advertisers were all very high-end. Thus I wasn’t that surprised when I saw that the price on the subscription card for a year of Esquire was well under $1/issue.

So if Dr. Dobb’s Journal is circling the drain, it’s not the current readership that’s to be blamed, or the Internet. It’s the lack of advertisers interested in reaching that readership, or the magazine’s ability to reach a readership that is interesting to a better-paying tier of advertisers.

Let’s merge managed object models!

There was a question recently on Stack Overflow asking how to handle cross-model relationships in managed object models. Now, the poster wasn’t asking about how to handle relationships across persistent stores — he was asking how to handle splitting a model up into pieces such that the pieces could be recombined.

It turns out that this is somewhat straightforward to do using Core Data. Let’s say you have a simple model with Song and Artist entities. I’ll write it out here in a pseudo-modeling language for ease of reading:

MusicModel = {
    Song = {
        attribute title : string;
        attribute duration : float;
        to-one-relationship artist : Artist,
            inverse : songs,
            delete-rule : nullify;
        userInfo = { };
    };

    Artist = {
        attribute name : string;
        to-many-relationship songs : Song,
            inverse : artist,
            delete-rule : cascade;
        userInfo = { };
    };
};

Now let’s say you want to split this up into two models, where Song is in one and Artist is in the other. You could just try and create two xcdatamodel files in Xcode, one with each entity, and wire the relationships together after loading them and merging them with +[NSManagedObjectModel modelByMergingModels:]. Except that won’t work: Relationships with no destination entity won’t be compiled by the model compiler.

What else might you try? You could try just putting dummy entities in for relationships to point to. However, merging models will fail then, because NSManagedObjetModel won’t merge models that have entity name collisions.

It turns out, though, that you can merge models very easily by hand, by taking advantage of the way Core Data’s model-description objects handle the NSCopying protocol. All you have to do is create your destination model, loop through every entity in each of your source models, and copy every entity that you haven’t tagged as a stand-in using a special key in their userInfo dictionary.

Why does this work? The trick is that before you tell a persistent store coordinator to use a model, that model is mutable and references relationship destination entities and inverse relationships by name. So you can have only a minimal representation of Artist in one model, and a minimal representation of Song in another model:

SongModel = {
    Song = {
        attribute title : string;
        attribute duration : float;
        to-one-relationship artist : Artist,
            inverse : songs,
            delete-rule : nullify;
        userInfo = { };
    };

    Artist = {
        /* Note no attributes. */
        to-many-relationship songs : Song,
            inverse : artist,
            delete-rule : cascade;
        userInfo = { IsPlaceholder = YES; };
    };
};

ArtistModel = {
    Song = {
        /* Note no attributes. */
        to-one-relationship artist : Artist,
            inverse : songs,
            delete-rule : nullify;
        userInfo = { IsPlaceholder = YES; };
    };

    Artist = {
        attribute name : string;
        to-many-relationship songs : Song,
            inverse : artist,
            delete-rule : cascade;
        userInfo = { };
    };
};

Then, when you write some code to combine them, the merged model will wind up with the full definition of Song and the full definition of Artist. Here’s an example of the code you might write to do this:

- (NSManagedObjectModel *)mergeModelsReplacingDuplicates:(NSArray *)models {
    NSManagedObjectModel *mergedModel = [[[NSManagedObjectModel alloc] init] autorelease];

    // General strategy:  For each model, copy its non-placeholder entities
    // and add them to the merged model. Placeholder entities are identified
    // by a MyRealEntity key in their userInfo (which names their real entity,
    // though their mere existence is sufficient for the merging).

    NSMutableArray *mergedModelEntities = [NSMutableArray arrayWithCapacity:0];

    for (NSManagedObjectModel *model in models) {
        for (NSEntityDescription *entity in [model entities]) {
            if ([[[entity userInfo] objectForKey:@"IsPlaceholder"] boolValue]) {
                // Ignore placeholder.
            } else {
                NSEntityDescription *newEntity = [entity copy];
                [mergedModelEntities addObject:newEntity];
                [newEntity release];
            }
        }
    }

    [mergedModel setEntities:mergedModelEntities];

    return mergedModel;
}

This may seem like a bit of overhead for this simple example. The critical thing to see above is that only that which is necessary for model consistency is in the placeholder entities. Thus you only need the inverse relationship from Song to Artist in ArtistModel. Say you wanted to add a Picture entity related to the Artist entity — you don’t have to add that to both models, only to ArtistModel. The benefit of this method for merging models should then be pretty apparent: It gives you the ability to make your model separable, just like your code.

Erlang on LLVM? or: Outsource your JIT!

Has anyone been working on using [LLVM][1] to do just-in-time code generation for the [Erlang][2] virtual machine?

Depending on the design and structure of the Erlang virtual machine, it doesn’t seem like it would be all that tough a project. And it could provide a nice performance boost for those projects that are starting to use Erlang like [CouchDB][3] and [ejabberd][4].

For an example of what I’m talking about, there’s a project called [VMKit][5] that has implemented the Java and .NET virtual machines atop LLVM with reasonable performance. Essentially, if you have a virtual machine, rather than skipping either just-in-time or static code generation entirely, or trying to do it all yourself for some specific platform on which you want to run, take a look at what you can do with LLVM and see if you can leverage its code generation instead.

[1]: http://llvm.org/
[2]: http://erlang.org/
[3]: http://couchdb.org/
[4]: http://www.ejabberd.im/
[5]: http://www.ejabberd.im/

Not it!

I didn’t write [Carrie’s Dots][1] — but I did download it!

It was written by [Dr. Chris Hanson][2], a Chris Hanson who’s evidently still in the mid-South. Maybe the next time I get a chance to visit Mississippi, we’ll get to meet up!

[1]: http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=286047207&mt=8
[2]: http://dr-chris.org/

LLVM terminology

I thought the proper terminology was worth pointing out, since I’ve seen — and heard — some misuses lately.

* **[LLVM][1]** is the Low-Level Virtual Machine and the project surrounding it.

* **[LLVM-GCC][2]** is a compiler that uses GCC for its front-end and LLVM for its back-end.

* **[Clang][3]** is the C language family front-end that is part of the LLVM project. It’s a parser, semantic analyzer, and code generator — in other words, a compiler front-end that uses LLVM for its back-end.

* **[The Clang Static Analyzer][4]** is what people have been trying out lately, to find subtle bugs in their and other projects. It’s a great tool.

I just thought this was important to mention, because people have been referring to “LLVM” instead of “LLVM-GCC” in reference to the compiler included in Xcode 3.1, and people have been referring to “Clang” instead of “the Clang Static Analyzer” in reference to what they’ve been using to find bugs in their projects.

[1]: http://llvm.org/
[2]: http://llvm.org/docs/CommandGuide/html/llvmgcc.html
[3]: http://clang.llvm.org/
[4]: http://clang.llvm.org/StaticAnalysis.html

New bike! Marin Belvedere 2007

I just got my first bike since junior high, and rode a bike today for the first time since high school! Many thanks to Meg for helping me pick it out and to Dan and others for listening to me ramble about what I might or might not want.

What I wound up getting was a 2007 Belvedere from Marin Bikes, in matte coal (of course). I test-rode it and it felt great, I could even shift — something I could never do in junior high or high school without losing control, damn post-shifters — and the only limit I felt with it was me!

So after accessorizing a bit, Meg and I rode home and then walked back to pick up the car. Cupertino and the South Bay in general are so bike-friendly I can tell I’m going to put a lot of miles on it just this summer, and if I get a good set of panniers there’s no reason I won’t be able to keep doing so into the fall and even winter.

And as tired as I am just from riding a couple miles today, it feels a hell of a lot better than contributing to the climate crisis while paying nearly $5/gallon for gasoline.

Always use notification name globals, not string literals!

What’s wrong with this code?

– (void)registerForNotificationsFromTask:(NSTask *)task ( {
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(taskDidTerminateNotification:)
name:@”NSTaskDidTerminateNotification”
object:task];
}

If you didn’t notice anything wrong, look again.

What’s bad about this is that it’s passing a **string literal** instead of a **global variable** for the notification name. The code should really look like this:

– (void)registerForNotificationsFromTask:(NSTask *)task ( {
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(taskDidTerminateNotification:)
name:NSTaskDidTerminateNotification
object:task];
}

Isn’t that better? (Among other things, Xcode will offer to complete the `NSTaskDidTerminateNotification` global variable for you — unlike the contents of a string literal.)

This is a bug that often results from copying & pasting from documentation into code. “I need this notification, it needs to be a string, so I’ll just put `@””` around it.” The *type* of a notification name is, in fact, `NSString` but you don’t have to pass a *string literal* for that. Instead, pass the global variable that exists for each notification name and you’re guaranteed that the right thing will happen.

If you’re creating and using your own notifications, be sure to follow the Cocoa pattern and create your own global variables containing the notification name. Otherwise you’re at the mercy of typos within string literals.

**Update:** Sanjay Samani helpfully pointed out that by *constant string* I meant *string literal*. Thanks, Sanjay! I’ve updated my post with this correction. (Not sure where my memory was…)