Rebutting Big Nerd Ranch on Objective-C 2.0 dot notation

The Big Nerd Ranch weblog has a new post about Objective-C 2.0 dot notation. They advocate never using it and they’re completely wrong.

Given my reaction on Twitter, several people have asked me to write a more in-depth rebuttal.

I’ve already addressed when and why you should use Objective-C 2.0 properties and dot notation in an earlier post, so I won’t go into that here. I’ll just repeat my response to their weblog.

Here’s what I wrote in response:

> I disagree most emphatically. The whole point of dot notation is that, when combined with properties, it’s not *just* an alternative syntax for invoking methods. In fact, if that’s how you think about dot syntax, STOP. That’s not what it’s for at all.
>
> What dot syntax and property declarations are for is separating object *state* from object *behavior*. Classical OOP only really defines objects as only exposing behavior but the past 30+ years have demonstrated rather aptly that objects consist of both. C# was actually pioneering in this; its concept of properties is rather similar to what the combination of property declarations and dot syntax enable in Objective-C.
>
> To write idiomatic Objective-C 2.0 you should use `@property` to declare properties, and use dot syntax to access them. Period. Doing otherwise is a bad idea because it will create code that isn’t intention-revealing to other experienced Objective-C 2.0 developers. Teaching students to do otherwise is doing them a disservice, because you’re directly contradicting those responsible for the language and its evolution.

In short, Objective-C 2.0 has properties and dot notation as another way of expressing intent in your code. Use them for that, don’t refuse to use them just because they weren’t in earlier versions of the language, or because they require teaching another concept.

Unit testing Cocoa user interfaces: Use Check Methods

In the past, I’ve talked about ways to easily write unit tests for Cocoa applications, including [tests for user interfaces using target-action][1] and [tests for interfaces using Cocoa bindings][2]. There are some strategies you can apply to make writing tests for Cocoa code even easier, though. They’re just straightforward object-oriented programming, but sometimes we can forget that all the techniques you might use in your main code base can also be applied to our test code.

So here’s one trick that you can use in writing tests for Cocoa user interfaces, especially in ways that will make test-driven development easier.

### Use a Common Base Class with Check Methods

The first, probably most important thing to do is *use your own common base class* for your tests. Don’t derive your tests directly from `SenTestCase`; instead, derive them from your own `MyTestCase` class that in turn derives from `SenTestCase`. This gives you a place to put all of the customization that’s appropriate for your project.

Sometimes you might need a series of assertions to verify some particular state. However, that series of assertions will be the same every time you need to verify that state. Or the assertions themselves aren’t very *intention revealing* so you always wind up putting a comment above them describing what they’re really doing.

### Checking Target-Action

A simple example of this is checking a target-action connection in a user interface. Say you have a view controller that presents a collection of objects managed by an array controller. Its view has an Add button that should send `-addObject:` to the array controller. You might write a test for it like this:

– (void)testAddButtonSendsAddObjectToArrayController {
STAssertEquals([viewController.addButton target], viewController.arrayController,
@”The Add button should target the array controller.”);
STAssertEquals([viewController.addButton action], @selector(addObject:),
@”The Add button should send the -addObject: action.”);
}

That’s not too difficult to understand, but it could be made simpler — it could be done in a single assertion. You’d just write a method to check both the target and action at once and then use that method from your test, like this:

// in your test base class…

/*! Tells whether the control sends the action to the target. */
– (BOOL)checkControl:(NSControl *)control
sendsAction:(SEL)action
toTarget:(id)target
{
return ([control action] == action)
&& ([control target] == target);
}

// in the tests specifying the view controller’s behavior…

– (void)testAddButtonSendsAddObjectToArrayController {
STAssertTrue([self checkControl:viewController.addButton
sendsAction:@selector(addObject:)
toTarget:viewController.arrayController],
@”The Add button’s action should send -addObject: to the array controller.”);
}

That makes the intention behind the entire test a lot clearer, and it makes writing the test easier & safer since you can’t (say) forget to check either the target or the action.

It *does* lose a tiny bit of information: If the test fails, you’ll have to look at your xib file instead of the failure message to determine whether it’s because the target or the action isn’t set as you’ve specified. However, the trade-off in making the test easier to read and write is worth it here.

### Checking Outlets

This is even worthwhile for single assertions, such as those you’d use to test that your outlets are connected in the first place. For example, you might initially write a test that your view controller is your table view’s delegate like this:

– (void)testViewControllerIsTableViewDelegate {
STAssertEquals([viewController.tableView delegate], viewController,
@”The table view’s delegate should be the view controller.”);
}

Rewriting it to be more intention-revealing with a simple check method would make it look like this:

// in your test base class…

/*! Tells whether the outlet is connected to the given destination. */
– (BOOL)checkOutlet:(id)outlet connectsTo:(id)destination {
return outlet == destination;
}

// in the tests specifying the view controller’s behavior…

– (void)testViewControllerIsTableViewDelegate {
STAssertTrue([self checkOutlet:[viewController.tableView delegate]
connectsTo:viewController],
@”The table view’s delegate should be the view controller.”);
}

You’re not saving any code by writing your test this way — you’re actually writing more — but its *complexity* has gone down because it requires less effort to see what it’s actually trying to do.

### Checking Bindings

This is even worthwhile in situations where you may still need a few extra assertions. For example, Cocoa bindings are specified using a lot more information than just outlets and target-acton connections; you won’t always want to check (and specify the value of) all of it, but you can easily make the common parts clearer.

Going back to our Add button example, as is typical its enabled state should be bound to the array controller’s `canAdd` property. Writing a test to specify this involves using `-infoForBinding:` and interpreting the results, which takes a couple lines of code and a couple of assertions:

– (void)testAddButtonEnabledStateIsBoundToArrayControllerCanAdd {
NSDictionary *bindingInfo = [viewController.addButton infoForBinding:NSEnabledBinding];
STAssertNotNil(bindingInfo,
@”The Add button’s enabled state should be bound.”);

id observedObject = [bindingInfo objectForKey:NSObservedObjectKey];
STAssertEquals(observedObject, viewController.arrayController,
@”The Add button’s enabled state should be bound to the array controller.”);

NSString *observedKeyPath = [bindingInfo objectForKey:NSObservedKeyPathKey];
STAssertEqualObjects(observedKeyPath, @”canAdd”,
@”The Add button’s enabled state should be bound through the ‘canAdd’ key path.”);
}

This isn’t too complicated, but it does start to get tedious, especially given that you have to remember to distinguish between `STAssertEquals` (pointer equality) and `STAssertEqualObjects` (object equivalence). Let’s put the tedium in one place:

/*! Tells whether the object’s binding is connected through the given key path. */
– (BOOL)checkObject:(id)source
hasBinding:(NSString *)binding
toObject:(id)destination
through:(NSString *)keyPath
{
NSDictionary *bindingInfo = ;
id observedObject = [bindingInfo objectForKey:NSObservedObjectKey];
NSString *observedKeyPath = [bindingInfo objectForKey:NSObservedKeyPathKey];

return (bindingInfo != nil)
&& (observedObject == destination)
&& [keyPath isEqualToString:observedKeyPath];
}

// in the tests specifying the view controller’s behavior…

– (void)testAddButtonEnabledStateIsBoundToArrayControllerCanAdd {
STAssertTrue([self checkObject:viewController.addButton
hasBinding:NSEnabledBinding
toObject:viewController.arrayController
through:@”canAdd”],
@”The Add button’s enabled state should be bound to the array controller’s ‘canAdd’ property.”);
}

Much clearer!

[1]: https://eschatologist.net/blog/?p=10 “Unit testing Cocoa user interfaces: Target-Action”
[2]: https://eschatologist.net/blog/?p=12 “Unit testing Cocoa user interfaces: Cocoa Bindings”

Objective-C 2.0 properties and to-many relationships

I’ve occasionally been asked about the appropriate form for properties representing to-many relationships in Objective-C 2.0.

Let’s start with the example of a recipe and its ingredients, represented by instances of the Recipe and Ingredient classes.

@interface Recipe : NSObject {
@private
NSMutableSet *_ingredients;
}

@property (copy) NSSet *ingredients;

@end

This is a pretty straightforward interface for the Recipe class, but how should we actually implement it? You might first think of writing something like this:

@implementation Recipe

– (id)init {
if (self = [super init]) {
_ingredients = [[NSMutableSet alloc] init];
}
return self;
}

– (void)dealloc {
[_ingredients release];
[super dealloc];
}

@synthesize ingredients = _ingredients;

@end

However, this **will not** do what you expect. In particular, whenever you manipulate the `ingredients` property, it always **replace the value** of the `_ingredients` instance variable used for its storage with a new, immutable NSSet!

What’s wrong with this? For one thing, you won’t be able to make any finer-grained changes to the `ingredients` property, so your code may wind up doing a lot of work unnecessarily. You’ll only ever post Key-Value Observing changes for the entire property, as well, not for individual manipulations; anything observing those changes will probably wind up doing extra work, too.

Why not instead change the type of the property itself to `NSMutableSet *` then? That way, your code could just manipulate the ingredients of a recipe directly, right? You *could* do that, but then you wouldn’t get **any** Key-Value Observing notifications for changes to the property. Why not? Because KVO is all about notification of **property** changes, and changing the object that stores a property’s data isn’t the same thing as changing the property itself.

What should you do then? Here’s how I would implement the `Recipe.ingredients` property instead of using the above `@synthesize` directive:

@implementation Recipe (IngredientsProperty)

– (void)setIngredients:(NSSet *)value {
[_ingredients setSet:value];
}

– (NSSet *)ingredients {
return [NSSet setWithSet:_ingredients];
}

@end

What’s different here is that I’m taking advantage of the fact that the instance variable backing the property is mutable. For just a getter and a setter, that isn’t a big deal. However, since I’m dealing with a to-many relationship, I wouldn’t just write a getter and a setter. I’d also write some of the additional relationship-KVC methods for the property, so I can manipulate the property more efficiently, and get finer-grained KVO notifications:

@interface Recipe (IngredientsProperty)

– (void)addIngredientsObject:(Ingredient *)ingredient;
– (void)removeIngredientsObject:(Ingredient *)ingredient;

– (void)addIngredients:(NSSet *)ingredients;
– (void)removeIngredients:(NSet *)ingredients;

@end

@implementation Recipe (IngredientsProperty)

– (void)addIngredientsObject:(Ingredient *)ingredient {
[_ingredients addObject:ingredient];
}

– (void)removeIngredientsObject:(Ingredient *)ingredient {
[_ingredients removeObject:ingredient];
}

– (void)addIngredients:(NSSet *)ingredients {
[_ingredients unionSet:ingredients];
}

– (void)removeIngredients:(NSSet *)ingredients {
[_ingredients minusSet:ingredients];
}

@end

By doing this, when I need to manipulate a Recipe’s `ingredients` property I can use `-mutableSetValueForKey:` to do so and any changes I make will be efficient. For example, if I’m creating a Recipe to represent Meghan’s Butternut Squash Panang Curry, I might write some code like this:

NSMutableSet *ingredients = [panangCurryRecipe mutableSetValueForKey:@”ingredients”];

[ingredients addObject:[Ingredient ingredientWithName:@”Butternut Squash” quantity:1]];
[ingredients addObject:[Ingredient ingredientWithName:@”Panang Curry Paste” quantity:1]];
[ingredients addObject:[Ingredient ingredientWithName:@”Coconut Milk” quantity:1]];

Instead of making several copies of the set as I make changes, the underlying mutable set is changed in as efficient a way as possible given the accessors I’ve implemented. I don’t have to do any extra work to make that happen.

I also get efficient KVO change notifications for the property, so if I have any user interface bound to it — whether through Cocoa bindings or, if I’m using Cocoa Touch, a “bindings lite” implemented atop KVO — the change notifications it receives will reflect exactly the changes made, instead of wholesale replacement of the set.

I could still improve the code above. I’m using `-[NSObject(NSKeyValueCoding) mutableSetValueForKey:]` to manipulate the `Recipe.ingredients` property. That means I don’t get nice Code Sense completion from Xcode, and have to remember the property’s name *and* spell it correctly when I use it in a string. So I’ll add the following property declaration and implementation:

@interface Recipe (IngredientsProperty)
@property (readonly, copy) NSMutableSet *mutableIngredients;
@end

@implementation Recipe (IngredientsProperty)

– (NSMutableSet *)mutableIngredients {
return [self mutableSetValueForKey:@”ingredients”];
}

@end

You’re probably thinking something like “Wait a minute, `readonly` and `NSMutableSet`?!” That’s exactly what I mean to say, though: You can mutate the *collection* you get back (“read”) from the property, but not the *property itself*.

> **Update:** On Twitter, a couple of people asked why I didn’t just use `-[Recipe addIngredientsObject:]` directly, since I have that available. I certainly could have done that, and it’d have all of the advantages I cite, and it wouldn’t require the creation of the proxy mutable set either. However, if I wanted to something more complex than just an addition, using the proxy mutable set is a significant advantage.
>
> This is because the proxy mutable set (or array, if you’re using an ordered relationship and `-mutableArrayValueForKey:`) will do the heavy lifting of figuring out the right combination of the accessors your implemented accessors to perform an operation most efficiently. Also, technologies like Cocoa bindings will always use the proxy.

With this additional property in place, the entire Recipe class will look something like this:

@interface Recipe : NSObject {
@private
NSMutableSet *_ingredients;
}

@property (copy) NSSet *ingredients;
@property (readonly, copy) NSMutableSet *mutableIngredients;

– (void)addIngredientsObject:(Ingredient *)ingredient;
– (void)removeIngredientsObject:(Ingredient *)ingredient;

– (void)addIngredients:(NSSet *)ingredients;
– (void)removeIngredients:(NSet *)ingredients;

@end

@implementation Recipe

– (id)init {
if (self = [super init]) {
_ingredients = [[NSMutableSet alloc] init];
}
return self;
}

– (void)dealloc {
[_ingredients release];
[super dealloc];
}

– (void)setIngredients:(NSSet *)value {
[_ingredients setSet:value];
}

– (NSSet *)ingredients {
return [NSSet setWithSet:_ingredients];
}

– (NSMutableSet *)mutableIngredients {
return [self mutableSetValueForKey:@”ingredients”];
}

– (void)addIngredientsObject:(Ingredient *)ingredient {
[_ingredients addObject:ingredient];
}

– (void)removeIngredientsObject:(Ingredient *)ingredient {
[_ingredients removeObject:ingredient];
}

– (void)addIngredients:(NSSet *)ingredients {
[_ingredients unionSet:ingredients];
}

– (void)removeIngredients:(NSSet *)ingredients {
[_ingredients minusSet:ingredients];
}

@end

And the code for creating the curry recipe becomes this, for which Xcode will give helpful Code Sense completion suggestions:

NSMutableSet *ingredients = panangCurryRecipe.mutableIngredients;

[ingredients addObject:[Ingredient ingredientWithName:@”Butternut Squash” quantity:1]];
[ingredients addObject:[Ingredient ingredientWithName:@”Panang Curry Paste” quantity:1]];
[ingredients addObject:[Ingredient ingredientWithName:@”Coconut Milk” quantity:1]];

As well, it continues to avoid making copies of the underlying collection representing the relationship, and it also continues to post fine-grained KVO change notifications rather than whole-property notifications, ensuring bound controls are updated efficiently.

So when you’re creating properties for to-many relationships whether they’re unordered (NSSet) or ordered (NSArray), consider using this approach to implementing them. It’ll take a little more code, but it’ll be a lot more efficient and more correct.

#### Bonus Round: Core Data

What about Core Data? Now that iPhone OS 3.0 has Core Data, in addition to Mac OS X, there’s **really** no excuse not to use it. But would you do anything differently above?

Of course. But since we’re talking about Core Data, it turns out that what you do different is actually *write a whole lot less code*. Here’s what the declaration of the Recipe class will look like if it corresponds to a Core Data entity:

@interface Recipe : NSManagedObject

@property (copy) NSSet *ingredients;
@property (readonly, copy) NSMutableSet *mutableIngredients;

@end

@interface Recipe (CoreDataGeneratedAccessors)

– (void)addIngredientsObject:(Ingredient *)ingredient;
– (void)removeIngredientsObject:(Ingredient *)ingredient;

– (void)addIngredients:(NSSet *)ingredients;
– (void)removeIngredients:(NSet *)ingredients;

@end

Notice that I’ve gotten rid of the instance variables section entirely. This is because Core Data manages the storage for your modeled attributes and relationships for you; you don’t need (and *really* don’t want) instance variables for them.

You’ll also notice that I put the additional to-many relationship accessor methods in their own category. To see why, take a look at the implementation of the class:

@implementation Recipe

@dynamic ingredients;

– (NSMutableSet *)mutableIngredients {
return [self mutableSetValueForKey:@”ingredients”];
}

@end

Notice anything missing? *All of the methods related to the modeled `ingredients` property!* Core Data will not only generate an efficient setter and getter for the `ingredients` property automatically at run time, but will *also* generate implementations for the other `ingredients` to-many relationship accessor methods as well!

Core Data will generate the methods (at the latest) when you try to use them; it’s not dependent on having the category declaration available. That’s just for the compiler and IDE’s benefit when you’re writing code that *uses* those methods, so they can be completed by Code Sense and the compiler knows not to generate unknown-method warnings.

#### Changes

I added a bit after the first use of `-mutableSetValueForKey:` to address why one might want to use the mutable set proxy rather than just using the finer-grained KVC accessor methods directly.

Singletons in Cocoa/Objective-C

I’ll preface this post with the standard advice: *Don’t create singletons if you don’t absolutely have to.* In general, if you’re creating a global “manager” object of some sort, you’re doing something wrong.

That said, there’s still occasionally a reason to have such a global singleton, such as a “default something.” The sample code in the Cocoa Fundamentals Guide goes to a lot more trouble than it needs to in order to *ensure* that a class is a singleton.

This is almost **never** what you want.

First off, you probably want your class to be testable in a variety of configurations. In your unit tests, instead of getting your shared singleton instance in your `-setUp` method and “resetting” its state in `-tearDown`, you’d be better off just instantiating a *new* instance in `-setUp` and *releasing* it in `-tearDown`.

Also, the example in the Cocoa Fundamentals Guide does a lot of work that it simply doesn’t need to. This is all you *really* need to do to create a singleton in Cocoa:

@interface SomeManager : NSObject
+ (id)sharedManager;
@end

@implementation SomeManager

+ (id)sharedManager {
static id sharedManager = nil;

if (sharedManager == nil) {
sharedManager = [[self alloc] init];
}

return sharedManager;
}

@end

That’s it! The astute reader will notice, of course, that this isn’t thread-safe. I got rid of the `@synchronized (self)` because it won’t do the right thing; depending on what actual class is sent `+sharedManager`, the value of `self` will be different!

For the sake of argument, though, let’s say that you do want a singleton with which you can interact from multiple threads at once. One way to do this would be to create your singleton instance in `+initialize` since it will always be run, on a single thread, before any other methods in your class:

@implementation SomeManager

static id sharedManager = nil;

+ (void)initialize {
if (self == [SomeManager class]) {
sharedManager = [[self alloc] init];
}
}

+ (id)sharedManager {
return sharedManager;
}

@end

By doing this, you avoid the performance bottleneck of `@synchronized` taking a recursive lock every time `+sharedManager` is invoked.

If you want to get fancier, and it’s OK to temporarily have more than one instance of your singleton created, you could even use `objc_atomicCompareAndSwapGlobalBarrier` to assign the value to return from `+sharedManager`, though this is probably also more work than it’s worth; after all, `+initialize` will only be invoked once for your class. (Though it can be re-invoked as a side-effect of initializing subclasses, hence the `if (self == [SomeManager class]) { }` idiom.)

In all of the above cases, you’ve done a whole lot less work than the example in the Cocoa Fundamentals Guide, and your code is a lot more likely to be correct as a result.

When to use properties & dot notation

I listened to a recent episode of the [cocoaFusion:][1] podcast about properties and dot notation today. There were a few interesting points brought up, but I felt a couple of the most important reasons to use `@property` declarations and dot notation weren’t addressed.

The biggest reason I see to use a different notation for both property declaration and property access than for method declaration and sending messages — even if property access ultimately results in a message send, as it does in Objective-C 2.0 — is **separation of state and behavior**.

In the ur-OOP days of Smalltalk, state was supposed to be *encapsulated* within objects *entirely*. This has become Smalltalk dogma and some developers have tried to propagate it to Objective-C: The idea that objects should *never* expose their state to each other, but instead only vend *behaviors*. It makes a certain amount of sense if you see objects purely as actors.

However, in today’s modern world we understand that objects aren’t *just* actors. Objects both “do things” *and* “represent things;” they’re nouns. And they have both *internal* state that they use in managing their behavior and *external* state they expose to the world.

You can use the same mechanism to do both, as Smalltalk does and as Objective-C did before 2007. However, it turns out that it can make a lot more sense to use different syntax to represent the distinct concepts, even if they’re handled by the same underlying mechanism.

For example, I might have a Person class and an NSViewController subclass that presents a Person instance in a view. The API to my Person class might look like this:

@interface Person : NSObject
@property (copy) NSString *name;
@property (copy) NSImage *picture;
@end

This sends a strong signal to the users of the class that `name` and `picture` are *external* state for a Person instance, leading me to write code like this:

Person *person = [[Person alloc] init];
person.name = @”Chris”;
person.picture = pictureOfChris;

The intent of this code is clear: I’m not asking `person` to do anything, I’m just manipulating its external state. That may cause it to do things as a side-effect, but at least in the code snippet I’m looking at, I’m just interested in changing some state.

Now let’s see what the NSViewController might look like:

@interface PersonViewController : NSViewController
@property (retain) Person *person;
– (BOOL)updatePicture;
@end

And let’s see how I’d use one, assuming it’s been instantiated and wired up in my view hierarchy already:

selectedPersonViewController.person = person;

if ([selectedPersonViewController updatePicture]) {
// note elsewhere that the person’s picture is updated
}

Even though the `-updatePicture` method has no arguments and returns a `BOOL` I (1) don’t make it a property and (2) don’t use dot notation to invoke it. Why not, since it fits the *form* of a property? Because it doesn’t fit the *intent* of a property. I’m actually telling the view controller to perform some action, not just changing some state, and I want the intent of that to be clear to a reader of the above code.

That brings me to the other major reason to both declare properties using `@property` and use dot notation to access them: Xcode. The code completion technology in Xcode tries hard to provide you with a good default completion and good choices in the completion list. But this can be very difficult, especially with the combination of Objective-C’s dynamic dispatch and the sheer size of the frameworks: There are hundreds (!) of methods declared in categories on NSObject as a result of categories describing informal protocols, and any of those methods could be valid on an arbitrary instance.

Dot notation, on the other hand, is **not** valid on arbitrary objects. Even though it compiles to exactly the same sort of `objc_msgSend` dynamic dispatch that bracket notation does, from a type system perspective it actually **requires** a declaration of the property being accessed to work correctly. The reason for this is that the name of a property is not necessarily the name of the message selector to use in dispatch; think of a property `hidden` whose underlying getter method is named `-isHidden`.

This means that tools like Xcode can provide a much more streamlined experience for properties using dot notation. If I write the above code in Xcode, rather than MarsEdit, Xcode will not offer completions like `-autorelease` and `-retainCount` when I type `person.` — it will only offer me the properties it knows are on Person.

Now, you *can* invoke arbitrary getters or setters (so long as they have a corresponding getter) using dot notation. The compiler doesn’t require an `@property` declaration for the use of dot notation, just a declaration. I could have declared the `Person.name` property like this:

@interface Person : NSObject
– (NSString *)name;
– (void)setName:(NSString *)value;
@end

The compiler will compile `person.name = @”Chris”;` just fine with this declaration, to an invocation of `-[Person setName:]` — but Xcode won’t offer you code completion for it if you don’t use `@property` to declare it. By not offering to complete non-`@property` properties for dot notation, Xcode avoids offering you *bad* completions like `autorelease` and `retain` that are technically allowed but are abominable style.

Of course, one complication is that many frameworks on Mac OS X predate `@property` declarations and thus don’t expose their state this way. That means Xcode won’t offer you completions for their state with dot notation until those frameworks do. Fortunately for iPhone developers, UIKit uses `@property` declarations pervasively. You should too.

To sum up:

* Use `@property` to declare the state exposed by your objects.
* Use dot notation to get and set objects’ state.
* Use method declarations to declare the behavior exposed by your objects.
* Use bracket notation to invoke objects’ behavior.

This results in intention-revealing code that clearly separates state and behavior both in declaration and use.

[1]: http://www.cocoafusion.net/ “cocoaFusion: podcast”

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.

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.

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/

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…)