Objective-C categories are an extremely powerful way to add functionality to an existing class. Take for example, the category below that adds some stack-like methods to NSMutableArray:
@interface NSMutableArray (StackAdditions)
- (id)pop;
- (void)push:(id)object;
@end
@implementation NSMutableArray (StackAdditions)
- (id)pop
{
id lastObject = [[[self lastObject] retain] autorelease];
[self removeLastObject];
return lastObject;
}
- (void)push:(id)object
{
[self addObject:object];
}
@end
Now let’s say that I was writing a plugin for any app in Mac OS X that had a plugin architecture, such as IB, Aperture, Address Book, etc. Now, let’s also say that these apps had the same category methods on NSMutableArray, but they were slightly different, maybe they didn’t retain the object because of a special need they had. Well, when my plugin gets loaded into the app, the Objective-C runtime will auto-magically replace their category with mine because they have methods with the same name.
Obviously, this presents a problem. Now whenever their code calls -[NSMutableArray pop] or -[NSMutableArray push:], then the runtime will use my implementation instead. And if their category relied on some special happenings in their implementation, then the entire app could quickly fall into an unstable and fatal state.
So what’s to be done? If you are writing an application that has a plugin architecture or you are writing a plugin for an app, you should run the application during testing with the environment variable OBJC_PRINT_REPLACED_METHODS set to YES. What this does is it tells the Objective-C runtime to print out any methods it replaces when loading in a plugin. If you see that your implementation is being overwritten or you are overriding someone else’s, then you know that you will need to change the name of your method to something else, such as -[NSMutableArray myPop] instead of the original method -[NSMutableArray pop].
As of Tiger, a new NSDateFormatter has been introduced to Foundation, and within it are a few things that might take some getting used to. So I will outline the date formatter in its entirety, and how to understand how all of the pieces work together.There are two main modes, or behaviors, of the NSDateFormatter: Pre 10.4 and 10.4+ (these same labels are used in Interface Builder).
- Pre 10.4 Mode (
NSDateFormatterBehavior10_0)
This mode was the only mode until Tiger was introduced, and it makes use of the the strftime-style format strings. The strftime format identifiers look like “%S” (seconds), “%m” (month number), and “%d” (day of month) to just name a few. Actually, the documentation for these identifiers is accurately described in Apple’s documentation that comes with Xcode or is found online at the ADC website.
UsageSo how might I go about creating a date formatter that exhibits the old Pre 10.4 behavior? Well, it’s actually quite simple. When you create your instance of NSDateFormatter, use the initWithDateFormat:allowNaturalLanguage: initializer, instead of the usual init method.You should note:Once you create the Pre 10.4 date formatter with a format string, you cannot change it. Though NSDateFormatter has a method setDateFormat:, it only applies to the new date formatter behavior. You can however, convert the date formatter to the newer behavior by calling setDateFormatterBehavior: and passing in NSDateFormatterBehavior10_4.
Sample code
NSDateFormatter *df = [[[NSDateFormatter alloc] initWithDateFormat:@"%1m/%1d/%y"
allowNaturalLanguage:YES]
autorelease];
// The following code will print something like 2/11/2007. Also notice how
// putting the '1' before the 'm' and 'd' in our format string took the padding
// zeros away.
NSLog(@"%@", [df stringForObjectValue:[NSDate date]]);
- 10.4+ Mode
NSDateFormatterBehavior10_4
Arguably the behavior you will want to use in your code is the 10.4+ Mode. This mode conforms to the Unicode TR35-4 standard, so it has a ton of features that the Pre 10.4 behavior just doesn’t have. For one, it uses different identifiers, the Unicode site at this link has all of the identifiers and how you can use them to construct date format strings. The documentation is mostly accurate except that though ICU claims three lower case e’s (”eee”) should evaluate to something like “Tues” or “Wed”, that isn’t reflected by the NSDateFormatter.
Changing the date format string
One of the really nice things about the new date formatter behavior is that you can set the date format string to something else after you create it. If you call setDateFormat: with some string, the changes are made immediately. This is nice if your date format string is dynamic.
Date and Time Styles
Another feature of the 10.4+ behavior is that you can tell it to ignore date format strings all together, and instead use the time styles defined by the user in System Preferences. These are set by each user on their own system in the International pane of System Preferences:

You can set a date or time style such as short, medium, long, full, or none at all. The methods for doing this are setDateStyle: and setTimeStyle:. The tricky part about using these styles programmatically comes in the order that you call those methods. For example, if you call setDateStyle: or setTimeStyle:, it voids the effect of the date format string. However, if after calling setDateStyle: or setTimeStyle:, you set the date format string by calling setDateFormat:, it then voids the time and date styles you just applied. The general rule of thumb is that whatever you call last is what the date formatter uses. If you set the date or time style last, it uses that; if you set the date format string last, then it uses that. The code below illustrates these little quirks.
// Create our date formatter and a sample date to work with
NSDateFormatter *formatter = [[[NSDateFormatter alloc] init] autorelease];
NSDate *date = [NSDate date];
// This will produce a date such as "07/11/2007 22:15".
[formatter setDateStyle:NSDateFormatterShortStyle];
[formatter setTimeStyle:NSDateFormatterShortStyle];
NSLog(@"%@", [formatter stringFromDate:date]);
// This will produce a date such as "07/11/2007", notice, without the time.
[formatter setTimeStyle:NSDateFormatterNoStyle];
NSLog(@"%@", [formatter stringFromDate:date]);
// This will produce a date such as "7 Nov 2007", thus nullifying the date
// and time styles we set above.
[formatter setDateFormat:@"d MMM yyyy"];
NSLog(@"%@", [formatter stringFromDate:date]);
// But now if I reset the date style, we nullify our date format string.
// And though I didn't reset the time style, since I reset the date style,
// the formatter assumes the use of both.
[formatter setDateStyle:NSDateFormatterShortStyle];
NSLog(@"%@", [formatter stringFromDate:date]);
The NSDateFormatter can be a tricky or intimidating class at first, but I think when you really unpack it, it is quite easy. Just remember:
- Two modes: pre 10.4 (
strftime-style, NSDateFormatterBehavior10_0) and 10.4+ (Unicode, NSDateFormatterBehavior10_4).
- When using pre 10.4 behavior, use
initWithDateFormat:allowNaturalLanguage: to create it. And remember, once you create it, you can’t change the format string.
- When using 10.4+ behavior, uses standard
init to create it. You can use a date format string or the date/time styles. And when setting these, remember that the last method you call is the style it uses (date format string versus date/time styles).
- Check out the Apple and Unicode documentation for a complete list of identifiers.
Probably the most common question asked about IB 3 is: how do you subclass something? In IB 2, it was easy, right? You could just go to the class browser, find the class you wanted to subclass (typically NSObject), subclass it with a name, and then instantiate an instance of that subclass. But, what happened to the class browser in IB 3? Interface Builder 3 goes back to the idea of M-V-C: model, view, controller. For those of you familiar with this concept, you can ignore this next sentence: model is where you write code pertaining to data, view is where you write code or make graphics for what users see, and then finally, controller is where you write code relating to the response of user events. Thanks to Cocoa, the interface code is all written for us, and we can benefit from just dragging objects out of a library in IB. Our typical use to subclass an object in IB is to create a controller object or something similar that our interface talks to.
Note: Interface Builder is not the place to write code, that is the role of Xcode. IB has the ability to generate code, but more for a traditional sense. So the idea is to create a class in Xcode, and then bring the knowledge of that class into IB. Thanks to the smarts of IB, you don’t have to do any work for this, since IB is in constant communication with the pieces of your project. If you create a class, IB knows about it the next time you switch to IB from Xcode.OK, enough talk, how do I do this? Here is a step-by-step guide to subclassing something to use in IB (the example below is creating a subclass of NSObject called AppController)
- Create your class in Xcode
In your Xcode project, add a new Objective-C class file by choosing New File… from the File menu. Name the file AppController.m.
- Instantiate your class in IB
The instantiation process is two-fold. First, switch over to IB, and from the Library, drag an instance of NSObject (which you can find using the filter text-field) into your Document Window.
And your Document Window should look something like this now:

So now you have just instantiated NSObject, but what about your subclass? To make the instance you just created descend from your subclass, select in the Document Window, and then open the Identity Inspector (you can do this from the Tools menu, or if you have the inspector open, it is the sixth segment with the little “i”). Once the identity inspector is open, at the top of inspector, there is a slice called “Class Identity”, and under that is a text-field labeled “Class”. In that text-field, start typing the name of your subclass. As you are typing, by the time you get to “App”, it should have auto-completed the text-field with the name of your subclass. Again, please understand here, you no longer have to tell IB about classes in your project because IB has automatic integration with your project.

And your document window should now look something like this, with the “Object” replaced by “App Controller”.

At this point you are done, but if you would like to add connectivity to your class, proceed to step 3.
- Add actions and outlets
Now that you have an instance of your subclass to work with in IB, you may very well want to add some connectivity between it and the interface. To do so, you can add outlets(IBOutlet) and actions (IBAction) to your class’s header file. To do so, go back to Xcode, and enter them where desired. If you need more help on this, please see the Cocoa tutorials on connections. Once you have created your outlets and actions in Xcode, switch back to IB, and by the time you do so, IB already has parsed your source code and found all of the outlets and actions, and they are now readily available for you to use.
So to quickly recap:
- Create your class in Xcode
- Switch to IB and add an instance of NSObject from the Library
- Change the instances class name to your subclass using the Identity Inspector
- Add actions and outlets
- Realize that subclassing in IB 3 is a lot easier than in IB 2
I saw some code for an alternative way to store instance variables for a class (instead of just declaring them in the class’s header). I will show the code and then explain it:
@implementation NSObject(ExtraOutlet)
static CFDictionaryRef externalFooTable = NULL;
- (void)setFoo:(id)value {
LazyInit(externalFooTable, ...); // This just initializes if externalFooTable is nil.
if (value) {
CFDictionarySetValue(externalFooTable, self, value);
} else {
CFDictionaryRemoveValue(externalFooTable, self);
}
}
- (id)foo {
return externalFooTable ? CFDictionaryGetValue(externalFooTable, self) : nil;
}
@end
OK, so what is going on here? Well, let’s say you have a class, and you have a instance variable called foo (and subsequent KVC methods). If you don’t use foo a lot, or if there are very few instances of your class that will have foo be something other than nil, than you can store the value of foo per instance in a static hash table. The key to the hash table per instance is the instance’s address (self in ObjC).
Because of this static hash table, if you have 1,000,000 instances of your class, and you only have one instance that has foo be something other than nil, than you are saving 3.815 MB of RAM! And imagine doing this for a complicated program with lots of classes and instances, you could really have a major performance boost.You can use this method on your own classes, or as the example suggests, add additional instance variables to classes you didn’t write like NSObject, NSString, etc.
Thanks co-worker Jon for teaching me this one.
I just posted the first release build for a command utility I wrote called GPMethods. It used for rapidly generating mutators and accessors for Objective-C. Instead of writing dozens of lines of setters, getters, and dealloc statements, GPMethods takes a list of property names and types, and then depending on the flag you give it, will produce the necessary code that you can paste right into your favorite text-editor.GPMethods is also really smart, and automatically tailors the generated output based upon the types you give it. For example, it will automatically release and retain properties that its thinks are objects, using the correct methodology whether it is a Cocoa, CoreFoundation, or even CoreGraphics object.Download the build at the GPMethods page.
I ran across what to me was not a seemingly obvious Cocoa artifact today. Let’s suppose that you create some strings much in the way I do below:NSString *myString1 = @"Kevin";NSString *myString2 = [[myString1 copy] autorelease];NSString *myString3 = [[[NSString alloc] initWithString:myString2] autorelease];NSLog(@"%p, %p, %p", myString1, myString2, myString3);Strangely, my log prints the following:0×6060, 0×6060, 0×6060meaning that all the objects are in the same address space! I didn’t quite understand how this could be considering the fact that I used three different methods to create a string. I tried the same thing with NSArray, NSIndexPath, and some others. Strange…After asking around, I finally got my response from Michael, a Cocoa veteran down the hall. He said, “try the same thing, but with mutable strings.”NSMutableString *myString1 = @"Kevin";NSMutableString *myString2 = [[myString1 copy] autorelease];NSMutableString *myString3 = [NSMutableString stringWithString:myString2];NSLog(@"%p, %p, %p", myString1, myString2, myString3);And sure enough:0xae60dd, 0xae60f7, 0xae60fd: different objects!So what’s the deal behind this? In Cocoa, when you allocated a new immutable string using any method, it checks to see if that string already exists in memory. If so, instead of actually allocating a new string, it just increments its retain count. You can imagine how handy that when you create 60,000 of the same string, and Cocoa just creates one with a retain count of 60,000.With mutable objects, however, we do not just bump the retain count because of the fact that if two sources create the mutable string “Kevin”, for example, and then one of the sources changes it to “Keeven”, they change in both places. Not a good thing. So mutable objects are actually allocated each time you create one.So watch out when you are doing pointer checking with immutable objects. You might not be getting exactly what you thought!
So I spent a few days trying to find a memory corruption bug, known as the infamous EXC_BAD_ACCESS. Basically that means that you are over-freeing zones of memory. In your GBD console, you will get some message like: *** malloc[705]: error for object 0×9c5b00: Incorrect checksum for freed object - object was probably modified after being freed; break at szone_error. Hmm. That really doesn’t tell us anything.The problem with malloc errors is that enabling zombies really doesn’t do anything, same with setting symbolic breakpoints in szone_error and malloc_error_break. So what’s the solution to finding this?Guard Malloc. Guard Malloc is a hard-to-find memory bug tracking utility that is part of libgmalloc.dylib. When you run with it enabled, for every malloc(), NSZoneMalloc(), or other associated memory allocators, Guard Malloc allocates its own virtual memory page, with the end of the allocated buffer at the end of the page. Therefore whenever you access outside of the buffer, it immediately causes a bus error. In addition, when memory is freed, libgmalloc deallocates its virtual memory buffer, so read and writes to the buffer also cause immediate bus errors. When running from Xcode with Guard Malloc, the Debugger will jump to the source where the bus error occurred making these bugs really easy to find.One issue with Guard Malloc is that because of all the paging, it takes a long time to do any operation. So be prepared to wait.Overall though, Guard Malloc is great and extremely helpful.