Let's merge managed object models!
[info]chanson
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.

LLVM terminology
[info]chanson
I thought the proper terminology was worth pointing out, since I've seen — and heard — some misuses lately.

LLVM is the Low-Level Virtual Machine and the project surrounding it.

LLVM-GCC is a compiler that uses GCC for its front-end and LLVM for its back-end.

Clang 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 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.

Always use notification name globals, not literal strings!
[info]chanson
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…)

WWDC 2008
[info]chanson
The time is upon us once again — WWDC time!

As I have the past few years, I'll be in San Francisco all week, staying at the Hotel Kabuki in Japantown.

And of course, I'll be around the conference all week — especially in the labs. Come by and say hi, and I'll be happy to help with any questions you have!

Down the Rabbit Hole: Four Years On
[info]chanson
Today was my four year anniversary working on developer tools at Apple.

No regrets about taking the red pill here!
Tags: ,

Xcode unit testing articles updated
[info]chanson
I've updated my posts on creating and debugging unit tests for for Cocoa applications and frameworks for Xcode 3.0. If you have any additional questions about how unit testing works in Xcode, don't hesitate to ask!

Here are pointers to the updated articles:

The most significant change is in debugging Cocoa application unit tests. There's an extra environment variable you'll need to add to your executable, DYLD_FALLBACK_FRAMEWORK_PATH, before you'll be able to debug it with Xcode 3.0. This is necessary because Xcode takes advantage of a new linker feature — runpath-relative install names — in order to support moving and renaming your Developer folder and having multiple versions of Xcode installed.

Unit testing Cocoa user interfaces: Cocoa Bindings
[info]chanson
About a year ago, I wrote about unit testing target-action connections for Cocoa user interfaces. That covers the traditional mechanism by which user interfaces have typically been constructed in Cocoa since the NeXTstep days. However, with the release of Mac OS X 10.3 Panther we've had a newer interface technology available — Cocoa bindings — which has presented some interesting application design and testing challenges.

Among other hurdles, to properly use Cocoa bindings in your own applications, you need to ensure that the code you write properly supports key-value coding and key-value observing. However, since the release of Mac OS X 10.4 Tiger, the necessary APIs have been available to easily do test-driven development of your application's use of Cocoa bindings, following a trust, but verify approach. (It's also been quite easy from the start to test your support for key-value coding and key-value observing, to ensure that your code meets the necessary prerequisites for supporting bindings. I can write more on this topic in another post if anyone is interested.)

The key to writing unit tests for Cocoa bindings is the -infoForBinding: method in AppKit's NSKeyValueBindingCreation informal protocol. Using this simple method, you can interrogate any object that has a binding for all of the information about that binding! It simply returns a dictionary with three keys:
  1. NSObservedObjectKey, which is the object that the binding is bound to;
  2. NSObservedKeyPathKey, which is the key path that is bound — in Interface Builder terms, this is the controller key path combined with the model key path, with a dot in between them; and
  3. NSOptionsKey, which is a dictionary of additional binding options unique to the binding. These are all of those additional checkboxes and pop-ups in the Interface Builder bindings inspector for setting things like a value transformer.
By specifying what this dictionary should contain for a particular binding, you can describe the binding itself and thus start doing test-driven development of your Cocoa bindings-based user interface. Note that all of the system-supported binding names — as well as the binding option names — are specified in <AppKit/NSKeyValueBinding.h> and are documented, too!

Let's take a simple example, like the one in last year's target-action example, of a window controller whose window has a static text field in it. The field should have its value bound to the name of a person through an object controller for that person. Assume that I've already created the test case and set up some internal methods on my window controller to refer to the contents of the window via outlets, and to load the window (without displaying it) in -setUp just like in the target-action example.

First, to see that my text field has a value binding, I might write something like this:
- (void)testPersonNameFieldHasValueBinding {
    NSTextField *personNameField = [_windowController personNameField];

    NSDictionary *valueBindingInfo = [personNameField infoForBinding:NSValueBinding];
    STAssertNotNil(valueBindingInfo,
        @"The person name field's value should be bound.");
}
Of course, this tells us nothing about how the binding should be configured, so it needs some fleshing out...

Let's check the object and key path for the binding.
- (void)testPersonNameFieldHasValueBinding {
    NSTextField *personNameField = [_windowController personNameField];

    NSDictionary *valueBindingInfo = [personNameField infoForBinding:NSValueBinding];
    STAssertNotNil(valueBindingInfo,
        @"The person name field's value should be bound.");

    NSObjectController *personController = [_windowController personController];
    STAssertEquals([valueBindingInfo objectForKey:NSObservedObjectKey], personController,
        @"The person name field should be bound to the person controller.");

    STAssertEqualObjects([valueBindingInfo objectForKey:NSObservedKeyPathKey], @"name",
        @"The person name field's value should be bound to the 'name' key.");
}
Not very exciting, and a little verbose, but it'll easily lead us through what needs to be set up in Interface Builder for this binding to work. If you want to cut down the verbosity, you can of course extract a method to do the basic checking...
- (BOOL)object:(id)object shouldHaveBinding:(NSString *)binding
            to:(id)boundObject throughKeyPath:(NSString *)keyPath
{
    NSDictionary *info = [object infoForBinding:binding];

    return ([info objectForKey:NSObservedObjectKey] == boundObject)
            && [[info objectForKey:NSObservedKeyPathKey] isEqualToString:keyPath];
}

- (void)testPersonNameFieldHasValueBinding {
    NSTextField *personNameField = [_windowController personNameField];
    NSObjectController *personController = [_windowController personController];
    
    STAssertTrue([self object:personNameField shouldHaveBinding:NSValue
                           to:personController throughKeyPath:@"name"],
    @"Bind person name field's value to the person controller's 'name' key path.");
}
If you're writing code that needs, say, a value transformer, it's a simple matter to extend this model to also check that the correct value transformer class name is specified for the NSValueTransformerNameBindingOption key in the binding options dictionary returned for NSOptionsKey.

You can even extract these kinds of checks into your own subclass of SenTestCase that you use as the basis for all of your application test cases. This will let you write very concise specifications for how your user interface should be wired to the rest of the code, that you can use to just walk through Interface Builder and connect things together — as well as use to ensure that you don't break it accidentally by making changes to other items in Interface Builder.

This is the real power of test-driven development when combined with Cocoa: Because you can trust that the framework will do the right thing as long as it's set up right, you simply need to write tests that specify how your application's interface should be set up. You don't need to figure out how to create events manually, push them through the run loop or through the window's -sendEvent: method, how to deal with showing or not showing the window during tests, or anything like that. Just ensure that your user interface is wired up correctly and Cocoa will take care of the rest.

Sometimes you just don't realize how good you have it
[info]chanson
Yesterday I was listening to the latest episode of Hanselminutes, Building a Developer PC, and Scott started talking about how he needed multiple CPU cores so he could take advantage of the new parallel build support in Orcas.

"Orcas" is Microsoft Visual Studio 2008.

Yes, 2008.

Say what you will about Xcode, but at least it's been able to build multiple files at once on multi-CPU machines for the better part of a decade.

(Also, how could anyone build the ultimate developer PC? You can't run Mac OS X on a PC you build, only on a Mac. Therefore it can't be ultimate. But if he were to get, say, an 8-core Mac Pro, he could run both Mac OS X and Windows on it. And those 8-way machines are pretty damn ultimate...)

Breaking on Objective-C exceptions
[info]chanson
At the latest CocoaHeads meeting, some questions came up about how to break when exceptions are thrown in Objective-C. It's pretty simple to do in Xcode, and I promised to explain how here. Just open the Breakpoints window, select the Global Breakpoints group at left, and add a couple of new symbolic breakpoints. Because you'll be adding them to the Global Breakpoints group, they'll be available in all of your projects. I have a number of breakpoints like that myself, for breaking when exceptions are thrown, when messages are sent to zombie objects, and so on. It's a really useful technique to learn, and the best place to get started is probably with exceptions.

The first of your symbolic breakpoints should be -[NSException raise] — for those who don't know, that's the standard Objective-C shorthand for "the raise instance method of the NSException class" — and it will be invoked any time an Objective-C exception is raised in the "traditional" fashion, which involves instantiating NSException or a subclass and sending a -raise message to the new instance.

The second of your symbolic breakpoints will be hit whenever a language-level Objective-C exception is thrown. Newer frameworks and applications — introduced after Mac OS X 10.3 Panther — tend to use this mechanism because it was newly introduced and is a lot more mainstream as its syntax is based on Java exception syntax. Just set your breakpoint on objc_exception_throw and you'll break whenever any code you're debugging hits a @throw construct.

I call the first mechanism the "traditional" one because before the addition of Objective-C's language-level exceptions in Mac OS X 10.3 Panther, Cocoa had a framework-level exception system implemented via the low-level C setjmp(3) and longjmp(3) calls and a set of exception-handling preprocessor macros. This mechanism is often used in frameworks introduced before Mac OS X 10.3 Panther, or in application-levle code that had to be binary-compatible with Mac OS X 10.2 Jaguar. As you can see above while the @throw construct can interoperate with older code, it has Objective-C runtime bottlenecks that it goes through.

Disable assertions and logging in your Release build
[info]chanson
Typically, when you create a build of your software to release, you'll apply a whole bunch of additional optimizations to that version that you won't apply to the debugging builds. You'll strip debugging symbols — or, nowadays, build them to a separate DWARF with dSYM file — and crank up the compiler optimization and instruction scheduling settings that would normally make debugging hard.

One optimization that's often overlooked, though, is to turn off assertions. A lot of developers will use assertion macros as sort of a "continuous unit testing" technique within their code during development. They'll assert that methods' preconditions hold, that the postconditions of various operations continue to hold, that changes within methods produce expected results, and so on.

Standard C provides the assert(3) macro to perform a simple form of verification. By default, it just writes the failure information — including the failing file and line — and then calls abort(3); most environments also provide a way to extend its functionality by using assert as a wrapper for a sub-macro or other function.

Similarly, Cocoa's Foundation framework provides a number of NSAssert and NSParameterAssert macros that you can use in your code. (The primary difference is in the message of the exception they generate.) These normally throw an NSInternalInconsistencyException, but their behavior is extensible by subclassing NSAssertionHandler.

The thing is, you probably don't want the released versions of your applications terminating immediately or throwing exception in unexpected places — even though you probably do want them to do so during development. (After all, that's part of how you ensure they won't happen in production, right?) So you need to disable them in your release build.

Fortunately, Xcode makes this really easy. You just need to add two entries to the Preprocessor Macros build setting in your Xcode project, typically at the project level (since you'll want it to apply to all targets in your project). To turn off Standard C assertions, you just need to specify NDEBUG while for turning off Foundation assertions, just specify NS_BLOCK_ASSERTIONS. If you do this, you can put assertions literally everywhere in your code but be confident you'll only ever hit them during development.

Logging is in a similar boat. The release build of an application should, in general, never log in normal use. However, it can be extremely useful when things do go wrong to allow your users to enable logging by changing a hidden (or not-so-hidden) preference within your application. Ideally, you could even control the logging for different aspects of your application and different levels of severity, so enabling logging for one piece of functionality doesn't affect others, and so you can avoid spewing more log information than necessary.

Unfortunately, there's no built-in facility in Foundation for this sort of fine-grained logging. There's really just NSLog which, though useful during development, is both unconditional and doesn't have either aspects or levels. However, there's the Open Source (BSD licensed) Log4Cocoa project which aims to provide most of this functionality. It's currently based on the same design as Log4J, and it hasn't had a lot of work since its introduction, but it's a good starting point for working sophisticated logging into your own applications and it would be great to see developers pick it up again.

Bob Frank and Wolf Rentzsch presented on both of them for Uniforum a few years back, and made a PDF of their presentation available. Just be sure to tune the logging that actually gets compiled into your release builds by leveraging the Preprocessor Macros build setting...

Update (April 30, 2007): I've followed this up with another post on the importance of distinguishing between assertions and checks in your code. One of the main reasons I find that people don't want to turn off assertions before shipping is that they're using assertions as checks; if you distinguish between them, then this won't be a problem.

CocoaHeads Silicon Valley at Apple on Thursday, April 12, 2007
[info]chanson
The next CocoaHeads Silicon Valley meeting will be on Thursday, April 12, 2007 from 7:30-9PM in the Hong Kong conference room at Apple. That's just inside the entrance to Infinite Loop 1, the main headquarters building at Apple's campus in Cupertino.

See the web site for details, directions, and the organizer's contact information.

R. Tyler Ballance will be talking about C#, Microsoft .NET 3.0 and Visual Studio.NET 2005 as someone who has used both platforms extensively. But don't worry, he's not pitching us on becoming a Microsoft developer! He'll be comparing and contrasting it with Objective-C, Cocoa, Xcode and Interface Builder — even covering some of what's coming in Leopard — and he may even cover what the Open Source community has to offer with Mono.

As always, we'll also be hanging out and talking about Cocoa in general, discussing new and cool things that have come up in the past month, and helping each other out. Join us!

Easily speed up your Xcode builds
[info]chanson
A lot of developers don't heavily modify the projects they instantiate from Xcode's templates. This is a shame, because not only is it a great way to learn Xcode in depth, it's also a great way to ensure your projects build as fast as possible!

To that end, then, here are two simple tips that you can apply to your projects right now that should get them building faster.

Normalize your build settings!

Projects and targets in Xcode have configurations — collections of build settings that influence how a target is built. The Debug configuration, for example, will typically specify the compiler optimization build setting with as low a value as possible. The Release configuration, on the other hand, will typically specify a relatively high value for this build setting. This begs the question: The Debug and Release configuration of what?

When you create a new project from one of Xcode's templates, the principal target in that project will typically have a number of build settings customized in its configurations. The project itself, on the other hand, won't have very may customized build settings. For the one-target-per-project case this doesn't matter much. However, if you create a project with multiple targets, you can wind up with a number of targets that specify the same (or even subtly different!) information.

Instead of leaving your project this way, you can normalize your build settings such that build settings you want to specify for every target in the project — for example, that compiler optimization should be off for the Debug configuration — are specified at the project level rather than at the target level. This takes advantage of the fact that build settings are inherited in Xcode; if a build setting isn't customized in a target, the value specified in the project is used.

What does this buy you? It ensures that you have a single, consistent set of settings that are passed to the compilers, linkers, and other tools that are used to build your software. That way you won't wind up with subtle bugs like code built with C++ RTTI turned on calling a plug-in built with C++ RTTI turned off. But just as importantly, it's enables the next trick, which can have a significant impact on the speed of large, multi-target builds.

Share your precompiled prefix!

Xcode, like many other IDEs, supports prefix files — header files that are included implicitly by every one of your source files when they're built. Normally, as I described above, these are specified in target configurations. The text in the prefix file that is copied out of Xcode's templates even mentions that it's for a specific target.

Don't be fooled!

Prefix files get precompiled for performance, so they can simply be loaded by the compiler rather than recomputed for every file you build. Precompiling a prefix file takes quite a bit of time though, especially if you use multiple languages in your project (such as C, Objective-C, and C++) because each language needs a separate precompiled prefix due to differences in how they'll treat "the same" code.

However, just because precompiled prefix files can't be shared between languages doesn't mean they can't be shared between targets. In fact, for performance, Xcode automates this sharing for you — if you meet it halfway. The critical thing that you need to do is to ensure that your prefix files are:
  1. Named the same; and,
  2. Built using the same compiler-related build settings.
That's where the normalization I talked about above comes in. You can even promote your prefix file-related build settings to your project instead of your targets, so you can be certain that they're shared.

In fact, if they meet the criteria that Xcode uses to determine whether precompiled prefix files should be shared, even multiple projects will wind up sharing them!

The pause between builds of a target's dependent targets to generate a new precompiled prefix file is like a pipeline stall: An unwelcome hiccup that holds everything else up until it's over. If Xcode can precompile a single set of prefix files at the start of your build and then re-use them for the entire rest of your build, it will stream past as quickly as it possibly can with only the occasional pause for linking. For large projects with a lot of dependent targets, this can make a big difference.

Separate your preprocessor macros!

"But Chris," you say, "I have target-specific preprocessor macros that I can't get rid of!" That's OK. As long as you don't need them in your prefix files, you can set them in the special Preprocessor Macros Not Used in Precompiled Headers build setting. These will be passed to the compiler when your sources are compiled, just like the regular Preprocess Macros will, but they won't be passed when precompiling a prefix file. So you can have your cake and eat it, too.

Of course, there are macros that you do want to set in your precompiled prefix headers, because they change the behavior. Macros like NDEBUG to turn off C assert or NS_BLOCK_ASSERTIONS to turn off Foundation's NSAssert are important to specify for your precompiled prefix files. Fortunately these types of macros typically differ only by configuration, and also remain consistent across targets and projects, allowing you to specify them at the project level rather than the target level.

Just these three small changes have the potential to make a dramatic difference in how quickly Xcode builds your project:
  1. Normalizing your build settings, so common settings across all your targets are specified at the project level;
  2. Increasing sharing of your precompiled prefix files by naming them consistently and using consistent compiler-related build settings; and
  3. Specifying separate preprocessor macros for your prefix files than for your targets,
Try it out and see for yourself!

Interface Builder helps you leverage MVC
[info]chanson
Kevin Hoffman, The .NET Addict's Blog: A NYC .NET Developer in Steve Jobs' Court - Day 1:
I took a step back and tried to figure out what the hell was going on. After a few minutes, I realized that Xcode was actually doing a really, really, really good thing. The vast majority of problems that arise from a poor separation of concerns between the GUI and the underlying code, model, and controller (if you even have such constructs in your app!) stem from the fact that you can double-click a button and immediately start writing code without thinking about the consequences of such a thing.

The NIB (stands for NeXTStep Interface Builder) file is a loosely coupled, standalone, user interface definition. It wouldn't make sense to double-click a button and immediately be taken to a code-behind. Instead, you have to create a controller class, and then ctrl-drag from the button to the controller and then pick the outlet you're going to use (something like click: or calculate:). To me, as a huge fan of the MVC pattern, this makes perfect sense. And it seems so elegant in its simplicity, and so incredibly cool in the fact that it is truly enforcing good design simply by the way the IDE works.
Kevin sees very clearly what sometimes takes people quite a while to realize: The design of Interface Builder and the design of the Cocoa frameworks go hand-in-hand to help you best leverage a model-view-controller architecture in your application and thus create something maintainable over the long haul. Interface Builder isn't just a "form painter" for a rapid application development environment that's discarded by the "more serious" developers — it's a critical piece of technology that every Cocoa developer can leverage to improve their application's design.

Unfortunately I can't say a whole lot about Leopard and its improvements to Interface Builder here. I can, however, point you to the Xcode 3.0 page on Apple's Mac OS X Leopard Sneak Peek site and the Leopard Technology Series for Developers at the Apple Developer Connection, which includes a great high-level Developer Tools Overview.

Leopard Developer Tools Overview
[info]chanson
There's a Leopard Developer Tools Overview now at the Apple Developer Connection!
The developer tools in Mac OS X Leopard are crafted for one mission: to enable you to create amazing applications. Offering a streamlined workflow, Xcode 3.0 helps you develop your applications faster than ever. The all-new Interface Builder lets you build awesome user interfaces that take full advantage of Leopard's capabilities. The new language features in Objective-C 2.0 speed up your development cycle. The innovative new Xray brings the ability to visualize your application at runtime in a way that's never before been possible. And, the brand-new Dashcode makes it a snap to create elegant and powerful Dashboard widgets.
It's the second article in the Leopard Technology Series for Developers, and boy is there a lot of meat there!

The article covers a whole lot of tools: Xcode 3, Interface Builder 3, the extremely innovative new Xray performance tool, and Dashcode, Apple's environment for creating Dashboard widgets using HTML, CSS, and JavaScript. There's a lot of coverage of Xcode enhancements including code folding, improved syntax coloring, inline display of errors and warnings, inline editing of breakpoint conditions, and mouse-over inspection of variables while debugging.

Of perhaps even more interest than the new tools to Cocoa developers will be some information about new language features in Objective-C 2.0 including fast iteration of collections using for ( … in …) syntax and properties that eliminate the tedium of implementing accessor methods and streamline accessor syntax.

Check it out!

Big, Flat Screen: Success!
[info]chanson
My new big, flat screen worked very well last night as a computer monitor. If I sit back on the couch it's just a little tough to use iChat and Xcode, though I suspect an updated prescription for my glasses could fix that. However, sitting forward makes everything just fine for browsing, coding, chatting, whatever. Not only that, but with picture-in-picture, I can have Adult Swim on in the corner of the screen while I hack!

In addition, the screen is so bright I had to turn it down to 75% brightness! I suppose it is 550cd/m^2, and the displays I'm used to are only about 300cd/m^2, so I shouldn't be too surprised. Still, it was impressive next to my MacBook Pro's otherwise-very-bright display.

The next addition is going to have to be a Mac Pro with a nice video card. The combination of a great display and a very fast computer will make it the ultimate gaming and development rig.

Big, Flat Screen: Westinghouse LVM-42w2
[info]chanson
I just took delivery on my new big, flat screen today. It's a Westinghouse LVM-42w2 42-inch 1080p monitor. No tuner — Who need one for HD, anyway? — and a 1920 by 1080 LCD panel with performance rivaling those of the Apple Cinema Displays. And lots of useful inputs.

I took delivery and set it up this afternoon to make sure it's all working and, um, wow. It's gorgeous. DVDs look great, and I bet high-definition content looks incredible. Plus, since it has a matte rather than glossy finish on the screen, it's a lot easier to view in my living room with the blinds open (or even closed) while the sun's up.

Tonight, I'll venture up to Fry's and pick up a DVI cable so I can see how usable Xcode is from my couch.

By the way, Appleseed makes for great demo material.

WWDC time again!
[info]chanson
It's WWDC time again for all of us in the Macintosh universe. I'm going to be up in San Francisco all week — if you've ever wanted to meet me, and you're at WWDC, this is your opportunity!

This year, instead of staying right across the border from Crackville, I'm staying at the Miyako in Japantown where JTAF is traditionally held. It's quite relaxing, though it's far enough out from Moscone West that I'll be taking a cab to the conference.

Unit testing Cocoa user interfaces: Target-Action
[info]chanson
It's really great to see that a lot of people are adopting unit testing for their projects and dramatically improving their quality. Test-driven development and agile development methodologies built around it are really taking off. However, a lot of people still feel that their user interface is difficult to test through code, and either requires a capture-playback tool or requires a different design approach based heavily on interfaces/protocols to get right.

In last year's post Trust, but verify. I tried to dispel some of the mystery of testing your application's user interface when using the Cocoa frameworks. However, I've still had a lot of (entirely well-justified!) requests for examples of how to put it into practice. So here's a simple example of what I'd do to write a unit test for a button in a window that's supposed to perform some action.

First, when implementing my window, I'd follow the standard Cocoa pattern of having a custom NSWindowController subclass to manage my window. This window controller will have an outlet connected to each of the views in the window, and will also wind up with a private accessor method — used only within the class and any subclasses, and in testing — for getting the value of each of its outlets. This design flows naturally from the test which I would write to specify that the window should contain a button. First, here's the skeleton into which I'd put tests:
// TestMyWindow.h

#import <SenTestingKit/SenTestingKit.h>

@class MyWindowController;

@interface TestMyWindow : SenTestCase {
    MyWindowController *_windowController;
    NSWindow *_window;
}
@end

// TestMyWindow.m

#import "TestMyWindow.h"
#import "MyWindowController_Private.h"

@implementation TestMyWindow

- (void)setUp {
    // MyWindowController knows its nib name and
    // invokes -initWithWindowNibName: in -init
    _windowController = [[MyWindowController alloc] init];

    // Load the window, but don't show it.
    _window = [_windowController window];
}

- (void)tearDown {
    [_windowController release];
    _window = nil; // owned by _windowController
}

@end
That's the infrastructure into which I'd put my other test methods for this window. For example, I'll want to specify the nib name for the window controller and ensure that it actually knows its window:
- (void)testNibName {
    STAssertEqualObjects([_windowController windowNibName], @"MyWindow",
      @"The nib for this window should be MyWindow.nib");
}

- (void)testWindowLoading {
    STAssertNotNil(_window,
      @"The window should be connected to the window controller.");
}
Now let's check that I have a "Do Something" button in the window, and that it sends an action directly to the window controller.
- (void)testDoSomethingButton {
    // _doSomethingButton is a private method that returns the button
    // conected to the doSomethingButton outlet
    NSButton *doSomethingButton = [_windowController _doSomethingButton];
    
    STAssertNotNil(doSomethingButton,
      @"The window should have a 'Do something' button.");
    
    STAssertEqualObjects([doSomethingButton title], @"Do Something",
      @"The button should be titled accordingly.");

    STAssertEquals([doSomethingButton action], @selector(doSomething:),
      @"The button should send -doSomething: to its target.");

    STAssertEquals([doSomethingButton target], _windowController,
      @"The button should send its action to the window controller.");
}
You'll notice something I'm not doing in the above: I'm not simulating interaction with the interface. This is the core of the trust, but verify approach to unit testing of your user interface.

I can trust that as long as I verify everything is hooked up properly that Cocoa will cause the button to send its action message to its target — whether it's a specific object or, if the target is nil, the responder chain — whenever the button is clicked while it's enabled and not hidden. I don't need to simulate a user event, and I don't even need to display the interface while running the unit tests. All I need to do is inspect, through code, that everything is wired up correctly.

Note that I can do way more than the above in testing my interface design, too. For example, I can ensure that the control layout is correct according to what my interface designer has specified, by checking bounding rectangles for example. But testing only the functionality of my interface has significant advantages, too. For example, it doesn't matter if I wind up using a custom kind of button to achieve exactly the kind of look and feel or behavior I need. It doesn't matter if I wind up changing the layout in response to feedback. No matter what I do, I'll know that functionality won't accidentally break while I'm messing around in Interface Builder — even if I completely rip out my interface and replace it with a new one!

This approach can also be used for testing Cocoa bindings using the -infoForBinding: method that was introduced in Mac OS X 10.4 Tiger. I hope to write up a post soon on how to approach Cocoa bindings using these same techniques, but it should be fairly straightforward given the above and the above documentation.

Update: I've struck through the check of the button's title above, because you may or may not want to do that. For example, if you're primarily running your unit tests against your development localization, you may want to put it in. But if you want to run your unit tests against a localized build of your application, you'll probably want to avoid checking a localized title against an English string. A "have your cake and eat it too" strategy might be to keep a variable somewhere in your application that can be used to selectively disable checks of only localized strings.

Update July 7, 2007: I've finally written a post, Unit testing Cocoa user interfaces: Cocoa bindings, on how to write tests for Cocoa bindings. Now there's no excuse for not doing test-driven development of your Cocoa user interfaces!

Checking Mac OS X applications for memory leaks
[info]chanson
A developer on the comp.lang.objective-c newsgroup asked recently how to check his Cocoa application for memory leaks.

Here's a simple process for using the leaks(1) command-line tool to investigate leaks in your applciation.
  1. Add some code to your application to wait instead of exiting, such as an atexit(3) callback that just sleeps:

      while (1) sleep(60);

    This ensures that your application stays around after it has otherwise completley shut down.

  2. Launch your application with the MallocStackLogging environment variable set to 1. You can set this by inspecting the executable — not the target — for your application. (See the malloc(3) manpage for more details on the environment variables that you can use with it.)

  3. Launch your application from within Xcode, run through a series of actions in your application, and quit your application. It should now be paused in your atexit(3) callback.

  4. Run /usr/bin/leaks against your sleeping application by specifying your sleeping application's process ID as its argument.

This will give you a list of blocks that leaks(1) thinks have been leaked from your application, their contents, and — thanks to the MallocStackLogging environment variable — the stack trace at the point each leaked block was allocated!

You can even do post-processing on this output to do things like format the stack traces and automatically file bugs against your application. Heck, you could even have your application have a debugging mode that launches leaks(1) And the best part: This isn't specific to Cocoa. It will work for Cocoa, Carbon, and even Unix tools. Anything that uses the standard system malloc(3) can be checked this way.

Xcode 2.3
[info]chanson
As Bill noted, Xcode 2.3 was released today! Check it out at the Apple Developer Connection!

There are a lot of great enhancements in Xcode 2.3, including both bug fixes and a seriously cool new feature: Dedicated Network Builds. To quote the release notes:
Dedicated Network Builds is a new feature in Xcode 2.3 targeted at developers of large projects with dedicated build farms for compilation. The existing distributed builds mechanism (distcc) does not scale past 6 to 12 builders, depending on network speed and host architecture. Dedicated Network Builds is designed to scale well beyond a dozen builders and has been tested with up to 32 builders. Dedicated Network Builds uses an advanced caching mechanism such that bandwidth between the build client (recruiter) and builders (volunteers) is minimized.
Very cool stuff!