Objective-C

There are 26 entries in this Category.

Safe key-value-coding

[Screenshot of the warning in action in Xcode]

Daniel Kennett recently posed the question on Twitter how many of us were defining symbolic constants for use with Key-Value-Coding and Key-Value-Observing. After all, string literals are bad, because they don’t get checked by the compiler, so any typo in them goes unnoticed until you realize your key-value-observer method is not called, or you’re getting back nil where a property really contains a value.

That immediately sent me musing that it would be nice to have something like @selector() for specifying properties as NSStrings. The nice part about @selector() is that, given you’ve turned on the Undeclared Selector warning (-Wundeclared-selector), it will complain if given any selector that the compiler doesn’t know about yet. Which is usually the case if you make a typo.

Five hours later, the idea suddenly came to me: A property’s getter is a selector! And @selector() already does the checking and presents an error message. And one can use NSStringFromSelector() to generate an NSString from any selector. Now, those two are a little wordy, but you can condense that into a neat little macro:

#define PROPERTY(propName)    NSStringFromSelector(@selector(propName))

Admitted, this burns a few additional cycles because it turns a string constant into a function call, but NSStringFromSelector() can probably take an existing string constant from inside the SEL data structure, and you can always take it out of your release builds by writing:

#if DEBUG
#define PROPERTY(propName)    NSStringFromSelector(@selector(propName))
#else
#define PROPERTY(propName)    @#propName
#endif

This turns your property name into the string constant we all know and love in release builds, but does the checking in your debug builds (if you’ve set up your debug builds with a -DDEBUG=1 flag like many people do).

The advantage of this is that you get checked selectors, even when doing key-value-coding and key-value-observing, without any performance impact on your users. If performance is a problem, you can even only use the checked version of PROPERTY() in a special ‘tests’ build of your app. But of course then you can still find yourself flummoxed at a missing KVO notification until you do that special build and it complains.

I’ve added this code to my UKHelperMacros collection of macros, which is available on my UliKit repository on Github.

PS – Thanks to Rob Rix for reminding me of the existence of the # operator, and Jens Ayton for looking up the warning name just when I started wondering why I was getting the warning in one project, but not the other.

Defensive Coding in Objective-C

When programming in a C-descended language like Objective C, there are many things that can easily go wrong. To avoid the worst of these errors, programmers have come up with various coding conventions that make it harder to cause such bugs. We’re not talking about indentation or spacing, but rather about “mini-patterns” that ensure certain errors are caught more easily. Here’s my spontaneous, certainly not exhaustive list:

Autorelease Early, Autorelease Often

When you allocate a new object that doesn’t immediately go into an instance variable, it is easy to forget to release that object and leak it. Even if you remember to call -release on it at the end of your method, someone might later add a return statement somewhere, and overlook there’s an object in need of releasing.

One way to fix this is to use goto and a bail: label to cause all exits from your method to go through one funnel point that releases everything again. Kind of a “dealloc method for your method”. goto is not inherently bad (that’s just a rumour brought about by a misinterpretation of the title of a paper by Mr. Dijkstra). That said, the code quickly becomes hairy if you have many different error exits from your method.

An easier way to fix this is to just remember to -autorelease the object right after you create it. That way, at the moment of creation, where it is glaringly obvious there’s an object in need of later cleanup (based on alloc/init or copy in the name), you already ensure you’re not leaking. If someone needs it later, they can always retain it explicitly. Leak-free code for free, and even for people with the attention span of a goldfish (Or poisson rouge, as my favorite leak-hunting colleague would say).

NIL Everything That Isn’t Bolted Down

The problem with C is that local variables are not initialized to zero. Nor are pointers to released objects cleared to nil. No, local variables contain arbitrary numbers that happened to be on the stack when they were created, and variables valiantly keep pointing at the spot that used to house your NSString long after you’ve released it. “There! Look! There’s a big bunch of nothing here that seems to be an NSString!”

A good way to avoid spending hours trying to track down dangling pointers is to set them to nil whenever they contain nothing. Every time you declare a pointer like

	NSString* myString;

stop yourself and instead initialize it properly

	NSString* myString = nil;

You’ll be grateful you did that the moment someone adds an if statement around a few lines that used to assign a value to this variable.

The same applies to objects that you dispose of. The moment you dispose of an object, set the variable that used to point to it to nil (be it an instance variable, a global, or just a local one). Again, in a complex function, someone might insert an if statement that releases your object, and miss that under certain conditions, the code you wrote still tries to access that object. When you later debug that code, nil will make it obvious the object is gone. On the other hand, any old pointer, probably still pointing at valid-looking remnants of the object that used to be there, will not obviously be invalid to you.

I’ve defined myself a DESTROY() macro like GNUstep has it to help with this. DESTROY() first releases an object, then sets its variable to nil. But I only write DESTROY(myVar);.

Don’t Use Accessors in Constructors or Destructors

This may sound a bit odd, but there is a reason to this madness. Constructors (i.e. -init methods in ObjC) and destructors (i.e. -dealloc or -finalize) are special methods: They are called before your object has fully been initialized, or may be called after it has already been partially torn down.

If someone subclasses your class, your object is still an object of that subclass. So, by the time your -dealloc method is called, the subclass has already been asked to do its -dealloc, and most of the instance variables are gone. If you now call an accessor, and that accessor does anything more than change the instance variable (e.g. send out notifications to interested parties), it might pass a pointer to its half-destructed zombie self to those other objects, or make decisions based on half-valid object state. The same applies to the constructor, but of course in reverse.

Now, some people say that accessors should not be doing anything but change instance variables, but that is utter nonsense. If that was all they’re supposed to do, we wouldn’t need them. Accessors are supposed to maintain encapsulation. They’re supposed to insulate you from the internal details of how a particular object does its work, so you can easily revise the object to work in a completely different way, without anyone on the outside noticing. If an accessor could only change an instance variable, you would have very limited means to change this internal implementation.

Moreover, I don’t think Apple would have introduced Key-Value-Coding and Key-Value-Observing if they didn’t agree at least partially that it’s fine to do a bunch of things in response to an accessor being used to mutate an object.

Mind you, all of this only applies to accessors being called on self from your constructor. If you’re setting up another object, you essentially have no choice but to use its accessors, and it would very often violate encapsulation if you did otherwise.

In Fact, Don’t Do Anything Big in Constructors and Destructors

The above rule can actually be made more generic: Whenever you do anything in a constructor or a destructor, try to think whether you really need to do it here and now. They’re mainly there to manage your instance variables. If you have to register for notifications or otherwise access external objects, it’s always safer to do it elsewhere, when you can be sure that your object has been completely constructed.

A neat trick in constructors is to call -performSelector:withObject:afterDelay:0 on yourself. This will ensure a method to initialize stuff gets called on your object the next time through the event loop. Of course, for many objects that opens yet another can of worms (imagine you’d just created an NSScanner and had to wait for the event loop to run once before you can use it!).

Another thing that sometimes works is to access external objects lazily. E.g. the first time someone calls any of the -scanXXX methods on an NSScanner, it could transparently and implicitly do some more involved setup and set a flag that this setup has happened.

I have a similar recommendation for destructors: You should try to close files or relinquish external resources explicitly, before your object is released, if you can. There’s nothing wrong in having code in your constructor that makes sure of this as well (i.e. to avoid leaking open file descriptors), but it is desirable to have that as a fallback, not as the preferred API.

Now, before you go all “goto considered harmful” on me: I’m not saying doing worthwhile things in constructors in destructors was bad. Rather, all I’m saying is that other options for good places to do it are often overlooked. Both because the whole matter of half-constructed/destructed objects can get hairy, and also because anyone else can retain your object and thus prevent your resource from going away.

If the object is by itself the resource, that is exactly what you want. It is what retain/release was designed for, after all. But if the resource simply represents a file or a hardware device, and someone deletes the file or unplugs the device, you must be able to cope gracefully with your object still existing because some nit retains it, even though the actual resource is gone.

And if you want to call methods that a subclass would want to override (and in Objective-C, there is no such thing as a “method that can not be overridden”, by design!), you’d prefer to have a fully-initialized object ready.

Follow Apple’s Singleton Design Pattern

There is a nice little example implementation of the Singleton design pattern on Apple’s developer web site. Implement it.

While I think the -retain/-release methods should actually be left alone so you get some decent crashes and notice when someone retains/releases a singleton the wrong number of times (retaining or releasing should be allowed on any object, even if just to make it easy to keep certain code agnostic of the precise type it’s dealing with, so we can’t just make it throw an exception), they got a lot of details right:

They don’t wait for -init to return to set the global singleton variable. After all, singletons can be subclassed, too (such a subclass usually gets instantiated instead of the superclass, as just like on Highlander, there can only be one). If any of the -init methods do anything that might trigger code that might in turn call your +sharedManager method (like, I don’t know, register for IOKit notifications and send NSNotifications when they come in), this would invite endless recursion. Since the singleton global hasn’t been set yet, that second call would create a second singleton instance, which would in turn trigger the notifications, which would in turn create a third singleton … and so on.

What Apple’s code does is to cleverly override +alloc to set the global variable. That way, it is already set before anyone ever gets around to doing anything with the object. They also have a lock on the class. So, even in a multi-threaded implementation, they only allocate the object once. Since they return nil on subsequent attempts to alloc the object, they also only ever allocate and init one object.

It’s a very solid implementation, and whenever I’ve taken a shortcut on this in the past (and the code on my site will show you I have been doing this this until fairly recently), it’s caused me pain. I’m glad I finally understand it now.

Clear Your Weak References

One convention in Cocoa is that you don’t retain your delegate. This kind of “weak” reference from the delegator to the delegate may seem dangerous at first, but makes complete sense in the common use case:

Usually, a controller object creates another object and retains it, and sets itself up as that object’s delegate to be able to modify or benefit from its behaviour. For example, an NSWindowController creates an NSWindow, becomes its owner by retaining it, and makes itself the delegate of that window.

Now, if the NSWindow retained its delegate, if it retained the NSWindowController, we would have a retain circle: When the NSWindowController is released by the last external party, it would still have a retain count of 1, because the NSWindow would have its delegate retained. However, the NSWindow would also have a retain count of 1, because the NSWindowController created the NSWindow and kept it retained. So both are waiting for the other to release them. Only then would their -dealloc methods get called, which would release the other one. They’d be like two lovers lost in space, separate from everyone else, but closely holding on to each other.

So, the rule was laid down: You don’t retain your delegate, as the delegate probably already owns you. But what happens if someone else retains the object you own? Your NSWindowController is released, it relinquishes its hold on the NSWindow by releasing it. But that other guy still has the NSWindow retained, so it stays open. Someone clicks your window and a delegate method is called.

Wait a second! The NSWindowController was the delegate! But it is gone!? Well, unless the NSWindowController was considerate enough to tell the NSWindow, by calling its -setDelegate: method and setting it to nil, NSWindow wouldn’t know. It would find itself yelling at a dead object, probably crashing.

So what have we learned? Unless you’re a fan of zombies, you’ll appreciate setting any weak references to yourself to nil in your -dealloc method.

In case you’re wondering who might be mad enough to retain your objects, look no farther than the deferred method call mechanisms, particularly NSTimer, NSThread, NSInvocation and the -performSelector:... family of methods that eventually end up with your NSRunLoop.

Of course, you can go and invalidate the timer, cancel the -performSelector:s, and in many cases you well should, but in other cases, you may actually want all of these operations to be performed on the object before it goes away (though maybe not in our example of an NSWindow). And of course this isn’t really a good example, because a good design would probably not install timers and the likes on objects but themselves (that usually violates encapsulation, after all). Then again, with NSInvocation you have no choice.

Use symbolic constants

Cocoa and Foundation make use of string constants for identification purposes a lot. Notification names, keys in NSDictionary objects. You also use them elsewhere, to refer to files on disk, processes using their bundle identifier etc.

Now, everyone knows that defining a string constant as a symbolic constant using #define or by defining it as a variable at global scope makes it easier to change this string later. Particularly if the string is used in several places. But often, people “know” that this constant will never need to be changed, so they just hard-code it. Bad idea. There are other advantages to a symbolic constant:

The Compiler knows about symbolic constants.

That is right. That means that, should you mistype the symbolic constant, the compiler will only see an unknown identifier. If you mistype a regular string constant, all the compiler sees is a string. A compiler has no idea that “MyPrettyColor” and “MyPrettyColour” are supposed to be the same thing, but one of them is obviously a mis-spelling. If you had defined a symbolic constant like

#define MyPrettyColour    "MyPrettyColour"

It would compile to the exact same code as using the pure string constant, but if you mistype MyPrettyColour as MyPrettyColor, the compiler would immediately tell you about that and you wouldn’t wonder why a dictionary value always gets returned as nil even though you know for certain you put it in the dictionary.

This applies similarly to any other kind of constant, be it an int, a double or whatever. It’s easy to hit 111111 when you meant to write 11111, and that excess digit is not always easily noticed, as our mind tends to “correct” what we see as it tries to make sense of it. If you define a symbolic constant, the compiler will catch any additional letter you type by accident. Even better, you can define the constant correctly. Tend to forget the U at the end of unsigned numbers? The constant will always contain it, you only have to think of it once. If you forgot it, you can simply add it, and all other spots that use the constant are magically fixed.

And last but not least, symbolic constants can improve readability. Imagine drawing code where you deal with margins, line widths etc. Now in one spot you draw a button, and in another you hit-test it. To do hit-testing, you inset your rectangle. What do you think is more maintainable?

buttonHotRect = NSInsetRect( [self bounds], 67, 42 );

or

buttonHotRect = NSInsetRect( [self bounds],
                             MyLeftMarginWidth + MyLineWidth + MyLineWidth
                             + MyRightShadowWidth + MyRightMarginWidth,
                             MyTopMarginHeight + MyLineHeight + MyLineHeight
                             +MyBottomShadowHeight + MyBottomMarginHeight );

If you ever change the drawing, how likely is that you’ll recall what separate numbers 67 or 42 were made up of? Any compiler worth its salt will fold the numeric constants and thus generate the same code for both of them. There is no reason to not go for readable code.

Closing words

Reading this, you may think I should just stop writing thoughtless or bad code instead of doing things like these to mask the issues. But the matter of the fact is: Everyone has a bad day, everyone makes a mistake. Particularly when you program in teams and you’re programming all week long and there are deadlines when you have to ship, the likelihood of mistakes increases.

And even if you’re not working in a team, remember the Zarra description of programming alone: You’re programming in a team of three people. Past You, who was a moron, Present You, who is average, and Future You, who is a genius. You’re already being annoyed by Past You‘s lack of skill, you don’t want to make it any harder on Future You.

Following the rules in this article will make many bugs more obvious while you’re debugging them, and will prevent many crashes from happening in the first place.

So, do you guys have any neat coding tricks to share that I forgot to mention?

Drawing off-screen in Cocoa

In general, drawing in Cocoa always happens in an NSView‘s -drawRect: method on the main thread. The OS calls that whenever you’re supposed to draw anything, and if you want to redraw, you use -setNeedsDisplay: to ask the OS to call you back, and it will in turn call -drawRect:.

But sometimes, you just want to draw on a secondary thread, or you want to draw something for later use that shouldn’t show up in the view right now. The approach mentioned above seems awfully limited, doesn’t it? Of course there are other ways to do that.

A very easy way is to just take an NSImage, create it in your helper thread or threaded NSOperation, call -lockFocus on it, draw your stuff, call -unlockFocus and then send the finished image back off to your main thread using -performSelectorOnMainThread:withObject:waitUntilDone:. Note though, that doing a -lockFocus on an NSImage pretty much deletes and recreates the image contents, along with a Graphics Context needed to draw into the image, so if you plan to lockFocus/unlockFocus a lot, this will be fairly slow. In this case, you might be better off creating an NSBitmapImageRep directly and drawing into that, or even creating a CGBitmapGraphicsContext, doing your drawing in there, and only creating an NSImage from that once you’re finished.

Since you decide what to do with the NSImage once you’ve created it, this is a decent way to cache drawing that will need to be displayed later, or to pre-render more detailed versions of tiles of an image in the background to allow for more detail when zooming. It is also a way to speed up drawing of complex stuff. The CPU and GPU are fast enough to blast a full-screen pixel buffer to the screen at 50fps or more, but actually doing anti-aliased rendering of bezier paths or laying out text at this rate might be taxing the machine a bit. It also means all your drawing resources are together on your secondary thread, completely disconnected from the main thread. So it’s unlikely your thread has to wait for someone on the main thread to finish drawing, unnecessarily slowing things down.

If you really, urgently need to draw now, and need to do it on another thread (e.g. for video playback), you’ll need to do the threaded NSView drawing thing: Call -lockFocusIfCanDraw on the view, do your drawing, being careful that all your state has thread-safety locks or is immutable, call -flushGraphics on the current context and then -unlockFocus again. This is a bit dangerous due to all the thread synchronization points, though, and doesn’t work all the way back across system releases, so don’t do that if you can avoid it. If you want to learn more, see Apple’s thread-safety documentation.

Classes are objects, too!

One of the things that confuses people about Objective-C, is the concept of a class method. Many people think that class methods are essentially functions with Objective-C method syntax, like class methods in C++ are. But that’s not true.

So, what are class methods? Well, if I wanted to confuse everybody reading this, I’d probably say something like “class methods in Objective C are exactly the same as instance methods”. While this is true from a low-level standpoint, if that were true on a higher level, we wouldn’t be making the distinction.

So, what’s the deal with class methods?

Well, in Objective-C, classes are actually also objects. The class of these objects is “Metaclass”. Confused yet? Well, until last year’s German Macoun conference, I sure was. Then Amin Negm-Awad explained it to me in his session on Objective C.

Maybe it helps to keep in mind that all method calls work the same way: The object gets asked what its class is, and the class gets asked whether it implements this method for its instances. If it doesn’t, the superclass gets asked the same question, and so on, until the proper (inherited) method is found in one of the superclasses. If a method was found, it then gets called, otherwise it fails (after a short attempt to let the object provide a fallback using -forwardInvocation: and the likes).

When the designers of Objective-C added class methods to the language, they had two options:

  1. Reimplement all that for class methods again.
  2. Make a class look just like another object to the code that takes care of this.

They went with the latter. They invented a special class called “metaclass” to stand in for the typical superclass, and made the compiler automatically create an object for each class you declare.

How are class methods called?

Why did they do that? That’s easy: Because that way, a subclass can override the class methods of its superclass. Yes, you heard right, if your base class has a method:

+(id)    factoryMethod
{
    MyBaseClass* newObject = [[[MyBaseClass alloc] init] autorelease];
    return newObject;
}

you can just replace that in your subclass with a method like

+(id)    factoryMethod
{
    MySubClass* newObject = [[[MySubClass alloc] init] autorelease];
    return newObject;
}

But you probably knew that. What you maybe didn’t know, is that “self” in class methods points at the class object. In our first case, that means we could actually write the first +factoryMethod above as:

+(id)    factoryMethod
{
    MyBaseClass* newObject = [[[self alloc] init] autorelease];
    return newObject;
}

The behaviour is exactly the same in the base class, when called as myVar = [MyBaseClass factoryMethod]. But in the subclass? Well, if you call this method on the subclass, as in myVar = [MySubClass factoryMethod], the same happens as would happen in a regular instance method call: The object at the start of the square brackets is the target and ends up in “self”. Just in this case, this is not an instance. It is the class object MySubClass itself.

If we don’t override +factoryMethod, the method we inherited from MyBaseClass gets called. With self being MySubClass, what gets executed is equivalent to:

+(id)    factoryMethod
{
    MySubClass* newObject = [[[MySubClass alloc] init] autorelease];
    return newObject;
}

since self is MySubClass here. Cool, isn’t it?

Throw in some introspection magic

People coming from other languages occasionally write code like the following:

+(void) showModalViewControllerForClass: (NSString*)className
{
     NSViewController* viewController = [[[NSClassFromString(className) alloc] initWithNibName: className] autorelease];
    [viewController showModal];
}

And then call it like

[MyModalViewControllerBaseClass showModalViewControllerForClass: @"MyModalViewControllerSubClass"];

Now, it’s cool that Objective-C lets you convert between strings and classes at all, but after my article on defensive coding, everyone should know that it is a mistake to pass a string literal instead of defining a constant. The compiler does not know that this particular string constant should contain a valid type name, so if you have a spelling error in the string, NSClassFromString returns Nil and this’ll quietly fail.

But before you go defining a constant so there’s only one place where you can mis-spell this string, think harder. There already is an identifier for this class. Yep, that’s right, you can just use [MyModalViewControllerSubClass class] to get the class object.

Okay, so we rewrite the method to:

+(void) showModalViewControllerForClass: (Class)theClass
{
     NSViewController* viewController = [[[theClass alloc] initWithNibName: NSStringFromClass(theClass)] autorelease];
    [viewController showModal];
}

and call it as

[MyModalViewControllerBaseClass showModalViewControllerForClass: [MyModalViewControllerSubClass class]];

right? It may be terribly verbose, but Uli has explained why it’s better code.

But that’s still bad code. As we learned above, every method called has a self pointer pointing to the target. In the case of class methods, this points to our class. So what we can do is rewrite this to be

+(void) presentModal
{
    UIViewController* viewController = [[[self alloc] initWithNibName: NSStringFromClass(self)] autorelease];
    [viewController showModal];
}

Of course, we also need to change our calls. Instead of calling the method on the base class, what we do instead is call it on the subclass:

[MyModalViewControllerSubClass presentModal];

And with two identifiers, one of which is a shorter, more concise method name, we do what we were doing with a string, two class names and a long method name, or, to avoid the string, two nested method calls.

Objective-C is full of such subtle goodies. So the next time you think something like “class methods are pointless”, “why do I have to pass strings” etc., look at the Objective-C language documentation. Chances are that there’s some neat feature you can find that, among other things, solves your problem much more easily for you.

So, why confuse us with all that “classes are objects” junk?

So far, I mainly talked about self and class methods, but there is one other thing you should take along from that whole “classes are objects” business: they really are objects. What that means is that you can store them in arrays or dictionaries, get them back out again and call methods on them. That you can send methods to them (calling class methods) and self gets set to the class is really just one useful side effect.

Have a file export plugin architecture? Load the plugin bundles and build an NSDictionary mapping each plugin’s file type to the bundle’s principalClass. Writing an interpreter? Build an array of your different instruction classes and instantiate them as needed… there might be hundreds of other opportunities to use classes as objects.

Custom Elements on WebKit Pages

Recently, I wanted to create a simple HTML editor. basically, I just wanted to WYSIWYG-edit styled text, and maybe insert a few images. But, of course there was one reason I could not use one of the existing HTML editors:

I needed to be able to insert special placeholder items. Little boxes, that could be double clicked for editing, and would otherwise just be part of the text like a regular character. In the final output, these would expand to special commands in a server-side scripting language, but I didn’t want to see them in the editor of course.

Luckily, after a bunch of code contributions and bug reports by Karelia, makers of SandVox, and then Mail.app using WebKit for editing styled e-mails, WebKit supports in-line editing. It is quite easy, actually: You just call [myWebView setEditable: YES] and give the WebView an empty HTML document. That is all you need to have a styled edit field from which you can get HTML and to which you can assign HTML.

Apple’s website also documents how to load HTML into the WebView, and how to get it back out. Loading is trivial using [[myWebView mainFrame] loadHTMLString: @"<html><body></body></html>"], and of course you can insert your HTML text in between these two tags. Writing them back out is slightly more complicated: What you do is get to the DOMDocument and then the documentElement from the mainFrame, then grab the element named @"body" out of that, and then you can typecast that to a DOMHTMLElement to obtain its innerHTML, which is a string containing the HTML for your styled text. If you want the full document and not just edit HTML fragments, you can simply take the document element’s outerHTML.

That was all straightforward so far, once I’d grown used to WebKit’s terminology. Now, how to manage the placeholders? Well, first, you will have to create a new WebKit plug-in project from the Standard Apple plug-ins category. This gives you a simple NSView, which you can associate with a MIME type by editing its Info.plist. Set up this project, so that it is built with your application project, and make sure you have a Copy Files build phase that copies it into a PlugIns folder in your application’s bundle.

You should now be able to specify an embed tag in your HTML source code with the type attribute set to your plugin’s MIME type, and WebKit will automatically load your plug-in and place it in this spot. However, you will either have to manually specify width and height attributes on the embed tag, or your plug-in will have to calculate the sizes, and use the arguments dictionary it gets passed on creation to add to them to the embed tag in code by manipulating the DOM tree through the DOMElement in WebPlugInContainingElementKey in the arguments dictionary. Since this key already refers to our embed tag, this is as simple as using the -setAttribute:value: call on this object, and using +stringWithFormat: to convert our sizes into strings.

What I learned from this? Once you know that there is no way to load a plug-in directly from inside your application, it is fairly straightforward to add your own objects to a WebView. Sadly, you always only know that after…

Cocoa Text System everywhere…

Sometimes, you need to draw text with more control than an NSTextField or NSTextView will let you do, and sometimes you need better performance than the NSStringDrawing category will provide. And maybe you need to draw text into a CGContext or even inside a Carbon application.

You may be thinking about CoreText right now, and how unfortunate it is that you still have to maintain compatibility with Mac OS X 10.4 “Tiger”, but there’s an easier way:

The Cocoa Text System

Just use the Cocoa Text System. The Cocoa Text System is a group of classes that NSTextView, NSTextField and NSStringDrawing use to actually draw strings. Now, if you look at Apple’s docs, you’ll first be frightened by how complex this whole system seems to be: there are NSLayoutManagers, NSTextStorages, NSTextContainers, NSGlyphGenerators, NSTypesetters… but don’t fear, it’s much easier than it looks.

Apple actually provides a great introduction in the Drawing Text with NSLayoutManager entry of the Drawing Strings Task Documentation.

If you read that, you’ll see that you actually only need to deal with three of these classes to draw any styled Unicode string wrapped to a text box: NSLayoutManager is kind of the main controller. The string to be drawn and its attributes are stored in an NSTextStorage, and the extents of the area to draw into is specified by the NSTextContainer. What’s more, once you’ve created these objects, you can cache them, and thus speed up repeated drawing of the same string significantly.

You create these objects using +alloc/-init as usual, then tell the layout manager to take ownership of the text container, and the text storage to take ownership of the layout manager. Here’s essentially Apple’s example:

NSTextStorage *textStorage = [[NSTextStorage alloc] initWithString:@"This is the text string."];
NSLayoutManager *layoutManager = [[NSLayoutManager alloc] init];
NSTextContainer *textContainer = [[NSTextContainer alloc] init];
[layoutManager addTextContainer:textContainer];
[textContainer release];
[textStorage addLayoutManager:layoutManager];
[layoutManager release];

// Use the objects.

[textStorage release];

To actually draw this example string, you simply specify the size of the area to draw in, then ask the layout manager for the range of glyphs to draw, and then tell it to draw those at whatever position you want:

[textContainer setContainerSize: rect.size];
NSRange glyphRange = [layoutManager glyphRangeForTextContainer: textContainer];
[layoutManager drawGlyphsForGlyphRange: glyphRange atPoint: rect.origin];

Pretty simple, isn’t it? Two things to watch out for here: Whenever you change the size of the text container, the text needs to be re-wrapped (“re-layouted”), which is a sort of expensive operation that can be sped up by caching. Second, to actually trigger such a re-layout, you call -glyphRangeForTextContainer:.

For drawing styles and images, you simply take advantage of the fact that the NSTextStorage is actually a subclass of NSMutableAttributedString. So, it’s trivial to assign styles, fonts, colors and add text attachments.

Measuring Text

For example, if you want to measure how much space text will use, set the text container to have the height or width of the fixed side, and set the other side of the rect to some huge value, like FLT_MAX. Then, you call -glyphRangeForTextContainer: to make sure the text has been layouted, and then call -usedRectForTextContainer: to get the actual dimensions of the text:

[textContainer setContainerSize: NSMakeSize([self bounds].size.width, FLT_MAX)];
(NSRange) [layoutManager glyphRangeForTextContainer: textContainer]; // Cause re-layout.
NSRect neededBox = [layoutManager usedRectForTextContainer: textContainer];

The Cocoa Text System in Quartz or Carbon

Carbon uses the straight Quartz APIs. People who want to draw into OpenGL textures, PDF contexts and other custom locations often also use Quartz directly. So, what if you want to use the above text drawing methods in Quartz? You don’t have a an NSGraphicsContext, you only have a CGContext. What to do? Well, easy. Behind every NSGraphicsContext, there is a CGContext, and for every CGContext, you can create an NSGraphicsContext. So, if you have the CGContextRef in a variable named inContext, you can easily do:

[NSGraphicsContext saveGraphicsState];
NSGraphicsContext* context = [NSGraphicsContext graphicsContextWithGraphicsPort: inContext flipped: true];
[NSGraphicsContext setCurrentContext: context];

// Do Cocoa drawing here.

[NSGraphicsContext restoreGraphicsState];

Of course, if you’re doing this in Carbon, take care to catch any NSExceptions and create an autorelease pool around calls like these, you wouldn’t want to leak Cocoa objects or have a Cocoa exception waltz through the Carbon system libraries.

The neat part about this is not only that the Cocoa Text System is much simpler than ATSUI, but also that the Cocoa Text system is very similar in design to CoreText. So, if you want to move to CoreText a couple releases from now, you’ll just have to swap out a few API calls, but the general workings will stay pretty much the same.

Using other people's classes

I have a bunch of open source classes on Github, so occasionally some kind people send me bug fixes. I’m grateful for that, and it’s one of the reasons why I make the code available. Some people also add new features, which is also very cool.

However, in many cases, they add new features by changing my class. And that always makes that little object-orientation alarm clock in my head go off: One of the reasons why subclasses are available in OOP is to let people use and modify library code without having to copy and paste or touch the original. If you change the class someone else writes, and that person decides that this change, for whatever reason, won’t be merged into the main code base, you will have to use FileMerge each time a new version is released, to apply your changes to the new version.

However, if you write a subclass that adds the features, you just drop in the updated base class, and the magic of inheritance will take care of doing the “merge” for you.

Mind you, I’m not complaining here. I’ve received some great submissions for some of my classes, from people like Todd Ransom, David Sinclair, David Rozga, and many others I’ve probably forgotten. Not to mention that, after I’ve stared at the same code for weeks, I just don’t see that missing [super dealloc] call anymore, and I’m grateful for the people who e-mail me and tell me. But I sometimes have plans for a certain class, and some changes some people suggest would collide with those. Or a certain change would break my or other users’ applications because it changes the behaviour of the class, and I have to turn it down.

If you write a subclass or a category that applies your changes, not only is your code completely self-contained and you don’t have to merge text files, it also makes it very easy for me to look at the code and see only your changes, without having to fire up diff myself, which may not be possible in an internet cafe anyway. And if I want to integrate it into the “official” version, I can easily copy and paste the stuff over. I’ll have to merge anyway, because I may also have made changes in the meantime.

Now, I won’t turn down a feature because it didn’t come as a subclass. I’m just saying that you could have a Shiny Happy Object-Oriented Feeling(tm), make it easy on yourself to get future updates until I get around to adding your modifications, and make it easier for me to check out your changes on the road.

Category or Delegate?

One of Objective C’s nicer features is the “Category”. A Category is simply a way to add your own methods to existing classes. And the best part of it: You don’t even need to have the source code to that class.

If you have some code for adding all those backslashes to a string so you can pass it to a command-line tool, then you can just put it into an NSString-category and immediately every NSString in your program understands this new method.

There’s just one problem with this: It’s very easy to mis-use. Since Object-oriented programming was invented, people seem to be oddly reluctant to create a new class. Also, many people have problems deciding when an object should e.g. be a dictionary and when it should only have a dictionary.

Whenever you extend a class (be it one of your own classes or an extension to another class using a category), or subclass, it helps to keep in mind that you want to keep your code easy to maintain. You want to reuse code so that you have to fix each bug only once in a central place and it’s fixed for good, and you want to take advantage of the fact that the less code you write, the less bugs can be in it.

So, to keep your code comprehensible at first read, your first question when extending a class should be: Does what I do still fit the name of the class? E.g. if you’re subclassing NSDictionary, what you end up with should in some way still be a dictionary. If you subclass NSDictionary and you end up with a data source, you should ask yourself whether what you’re doing is really such a good idea.

The second question you should be asking yourself is whether you’re crossing any boundaries. E.g. in above example of a dictionary (part of the “model” layer in the Model-View-Controller pattern) that gets subclassed and becomes a data source (which, strictly spoken, is part of the controller layer, though it’s mainly a “model-controller”), you’re watering down the MVC boundaries that are so useful in synchronizing multiple views with your data or keeping your application portable. It would probably be much better to create a new “DictionaryController” class that can connect to a dictionary. Of course you can give it the optional feature of creating the dictionary if needed (it would have a dictionary, not be one).

The third question should be: Is this really reusable? If you subclass NSMutableDictionary as a data source, what happens if you suddenly have an NSDictionary? The code to view an NSMutableDictionary or an NSDictionary is exactly the same, but your subclass would have to be reimplemented for both of them. No good idea. Better create a controller that can then be given either type of dictionary. Sure, you could use a category on NSDictionary, and NSMutableDictionary would probably inherit that, but there’s still point four below…

An extension of this reuse consideration is the thought of rewriting: If you write a category and immediately realize that for one very common use you’ll probably end up needing you’d have to rewrite it, maybe even as a separate object, then it probably isn’t reusable enough. Categories and objects aren’t very different in effort and lines of code. A category is usually self-contained and reusable, so it should probably have its own file, just like a class. So, if something might work better as a class, just make it one, it doesn’t hurt. And in addition, a separate object can be easily instantiated in a NIB and connected to another object. With a category and an existing object, that’s not so easy.

Categories are also where question four comes in: If you’re creating a category, do you really want to carry those methods around with every object? This is not a peformance consideration, but rather one of complexity and unwanted side effects. After all, it’s perfectly all right to write a classic C function that converts an object to another type if you only need that in two places, and it’s just as reusable to have a separate controller object that does repeated conversion and translation between data types (like NSFormatter). The ground rule is, if you can’t honestly say to yourself that you will use a particular method in a category on another class a dozen times, you probably shouldn’t be adding it.

As you see, there’s no hard and fast rule when to use a category and when not to (well, at least I haven’t managed to formulate it yet). But hopefully my rambling above will give you a checklist to go through mentally when you’re trying to decide whether a category, subclass, or a new class would be better in a particular situation.

If you have any suggestions, or have insights of your own to share, feel free to leave a comment.

Cocoa ground rules

Since I’ve seen many people violate two ground rules of object-oriented programming (OOP), I thought I’d list them here, in the hopes it’ll help some beginners not fight the frameworks but rather go with the flow in Cocoa.

  1. Encapsulation: Every object is supposed to be self-contained and go about its work without needlessly exposing internal details. In particular, you have no business looking at its retain count. Retain counts are there to let several objects share ownership of another object without having to care about their co-users.

    So, trying to make sure the retain count of an object hits zero when you’re finished is silly because the object may even internally retain and release itself until some important piece of work has been finished, and if you force it to go away, you’ll break it.

    The advantage of encapsulation in practice is that if you create an object of your own and need to completely change the way it does its work in a later revision, you can simply swap it out for another object that works differently (and may or may not create helper objects that retain it) without the rest of your app needing any changes.

  2. Maintainability: When you program, you spend only a fraction of your time writing code, and a lot more of your time reading it. Even while you write code, you are constantly glancing at the code you already wrote. So, write your code so it’s easy to read and easy to fix bugs, not so you save a couple minutes typing.

    The main tools for making code easy to read are to factor it cleanly (i.e. to make sure functions and methods aren’t several pages long), breaking out stuff you use repeatedly into helper functions (your code will then read like while( GetNextObject() ) PrintThisObject(); instead of being hundreds of instructions to sift through), and to not copy code but rather to share code, so that when you fix a bug in the one shared copy it is fixed in the whole program.

    Object-oriented programming encourages code reuse. So, don’t think “blimey, I have to create another class,” but instead think of how much code you’ll save writing in the future if you take this particular functionality and extract it into a small, self-contained object.

    The self-contained part is a good indicator here, especially if it’s an object that can work like a filter, i.e. take input, process it in some way and then give output, it’s a good candidate for a class of its own. Like a list of applications: It takes an array from a file (Preferences?), allows modifying this list, saves the list, and of course allows other code to use this list for their own nefarious purposes (like, refuse to run if one of these applications is running).

If you look at Cocoa itself, a lot of its classes are split in a way that they perfectly encapsulate or allow reuse of their functionality. So, the best way to learn OOP is to emulate the way your framework does objects and classes.

A pitfall with class reuse

After writing the previous note about the two most important things in object oriented programming, I realized that there’s one pitfall I may want to point out. Let’s show it based on an example:

A while ago I wrote a UKBorderlessWindow class. It’s a subclass of NSWindow that forces the NSBorderlessWindowMask flag. The advantage of this is that I can now create a borderless window in Interface Builder by simply setting this class as an object’s “custom class”.

I used this in several projects, and suddenly realised bugs I had already fixed were popping up again. What had happened? Well, I had violated the API contract. You see, every class, every method you create is a contract with the code using it: “This class does X.” The code expects that contract to be true. Trouble is, sometimes there is implicit behaviour that you don’t realize until you use the class in several projects. A borderless window is only borderless. What I did was that in one app I realised that my borderless window was ending up behind menus, but I wanted it on top. So I modified the class to put the window in a higher layer. Trouble was, another app using this window class was expecting the old layering…

What I should have done was create a new UKCoveringBorderlessWindow class that does the different layering. So, be sure your class names match what the class does, and don’t add stuff to a class that doesn’t fit its name. Either the name has to change, or you need a new class (or subclass).