Advanced programming tips, tricks and hacks for Mac development in C/Objective-C and Cocoa.

Supersequent implementation

Ever wanted to override a method using a category but still invoke the default method from the category? Like invoking the super method on a super class, this example will show you how to invoke any "supersequent" method no matter if its on the super class, the current class or even another category on the current class.

Method swizzling

In my opinion, the most fun feature of Objective-C's dynamic method lookup is being able to replace methods at runtime. For example, if you wanted to know when the -[NSWindow dealloc] method gets called and you're not using a subclass of NSWindow, you can exchange the normal -[NSWindow dealloc] method with one of your own methods and set a breakpoint or perform any logging work in your own code, before calling the original implementation.

This is done through an approach called method swizzling. An example of Method swizzling to replace -[NSWindow dealloc] method would work like this:

  • Create a class, MyClass, with a class method, +(void)myReplacementMethod
  • Put the following code at the start of your main() function:
Method myReplacementMethod =
    class_getClassMethod([MyClass class], @selector(myReplacementMethod));
Method windowDealloc =
    class_getInstanceMethod([NSWindow class], @selector(dealloc));
method_exchangeImplementations(myReplacementMethod, windowDealloc);

Prior to Objective-C 2.0 (in Mac OS X 10.5 Leopard) this code was a lot uglier. Google "method swizzling" and you'll see how people used to do it. Jonathan Rentzsch even wrote a library to handle all the different variations.

The contents of myReplacementMethod will now be called instead of NSWindow's dealloc. Conversely, if you wanted to invoke the original NSWindow method instead, all you need to do is invoke [MyClass myReplacementMethod]. This allows you to invoke the original implementation from your replacement implementation if you want to do so.

Limitations to method swizzling

The biggest limitation to method swizzling is that it only works if the method is implemented at the level you are trying to replace.

In the above example, this means that NSWindow must implement dealloc for us to replace it. If it merely uses an inherited version of dealloc then we must replace it at the NSResponder or NSObject level, affecting all NSResponder or NSObject objects, even if we only wanted to replace it for the NSWindow objects.

In addition, documentation rarely reveals whether classes implement overrides of inherited methods. So if you're trying to swizzle a specific method at a specific level in a hierarchy, you don't really know if it will be there until the swizzling fails or succeeds. And since overrides are typically "unpublished", you don't have any guarantee that it will remain there in the future.

It would be nice to have an approach which could replace at the NSWindow level, whether or not the method is implemented at that level.

A better proposal

I would like to be able to create a Category on a Class that overrides the method to replace but still lets me invoke the original method, like a "super" invocation but where it doesn't matter if the "super" method is on the current class or a super-class.

In the -[NSWindow dealloc] example, I just want to create -[NSWindow(MyOverrideCategory) dealloc] and still be able to invoke -[NSWindow dealloc] from my override.

Objective-C lets you create overrides in Categories but it prevents you from invoking the original implementation. This limitation occurs because Objective-C's "super" invocations only ever start from the super-class but Categories override methods on the same class.

This means, is that if you invoke [super dealloc] inside -[NSWindow(MyOverrideCategory) dealloc] it will invoke -[NSResponder dealloc] not the default NSWindow version.

I want to be able to invoke the "method immediately before the current method in the method lookup, no matter if its on the current or a super class".

Supersequent implementation

I didn't invent the word "supersequent" but I've never seen it applied to method lookup before. It seems about right in this case because we're looking up the next implementation in the "super" direction but it may not necessarily be a "super" method.

An invocation of the supersquent method implementation follows. This example shows a Category of NSWindow overriding dealloc and then invoking the default version.

@implementation NSWindow (MyOverrideCategory)

- (void)dealloc
{
    invokeSupersequent();
}

@end

Obviously, the magic is contained in invokeSupersequent(). This is a C preprocessor macro whose implementation is shown below.

No parameters to invokeSupersequent are needed here but the macro takes a variable argument list. The full set of method parameters (dealloc has no parameters) must be passed into invokeSupersequent() to be received by the supersequent implementation. The compiler will not warn you if you get this parameter list wrong, so you must be careful with it.

You can also use "return invokeSupersequent();" if you want to return the result of the supersequent invocation.

The lookup itself is relatively safe in that it will invoke any "super" implementation instead, if an appropriate next implementation is not found on the current class. The current implementation (shown below) is a little rough in that it tries to invoke nil when no "super" implementation exists at all but you could easily test for a nil result if you were concerned about that possibility.

The solution

The process works like this:

  1. Find the IMP of the current method.
  2. Look through the current Class's hierarchy and find the next method in the list after the current method (identified using the IMP from step 1) that responds to the same selector.
  3. Invoke that method

Step one comes from my earlier post of the same name.

Step two is just a series of iterations over the current Class' methods. It looks like this:

@implementation NSObject (SupersequentImplementation)

// Lookup the next implementation of the given selector after the
// default one. Returns nil if no alternate implementation is found.
- (IMP)getImplementationOf:(SEL)lookup after:(IMP)skip
{
    BOOL found = NO;
    
    Class currentClass = object_getClass(self);
    while (currentClass)
    {
        // Get the list of methods for this class
        unsigned int methodCount;
        Method *methodList = class_copyMethodList(currentClass, &methodCount);
        
        // Iterate over all methods
        unsigned int i;
        for (i = 0; i < methodCount; i++)
        {
            // Look for the selector
            if (method_getName(methodList[i]) != lookup)
            {
                continue;
            }
            
            IMP implementation = method_getImplementation(methodList[i]);
            
            // Check if this is the "skip" implementation
            if (implementation == skip)
            {
                found = YES;
            }
            else if (found)
            {
                // Return the match.
                free(methodList);
                return implementation;
            }
        }
    
        // No match found. Traverse up through super class' methods.
        free(methodList);

        currentClass = class_getSuperclass(currentClass);
    }
    return nil;
}

@end

And finally, step 3 is encapsulated in a macro which handily invokes the other two steps for you.

#define invokeSupersequent(...) \
    ([self getImplementationOf:_cmd \
        after:impOfCallingMethod(self, _cmd)]) \
            (self, _cmd, ##__VA_ARGS__)

I've been unable to get this macro to work on the iPhone when passing no parameters because it is not correctly stripping the final comma. In this case, I use the following:

#define invokeSupersequentNoParameters() \
	([self getImplementationOf:_cmd \
		after:impOfCallingMethod(self, _cmd)]) \
			(self, _cmd)

Warning about these macros

These macros use the IMP in an uncast way. This means that the compiler will treat the method as though it returns id and takes a variable argument list (since this is how an IMP is declared).

If your method returns something that is passed differently to an id (like a double or a struct) or some of your method arguments are structs or integer values shorter than a pointer, then you will need to cast the IMP to the correct signature before using or the parameters won't be passed correctly.

So for a method that takes a char and an unsigned short parameter and returns a double you would need:

IMP superSequentImp =
    [self getImplementationOf:_cmd after:impOfCallingMethod(self, _cmd)];
double result =
    ((double(*)(id, SEL, char, unsigned short))superSequentImp)
        (self, _cmd, someChar, someUShort);

Hideous but required if any of the following is true:

  • your return type is not a pointer or smaller size value (floats are acceptable)
  • your parameters not pointers, pointer sized integers (long or NSInteger) or doubles.

Conclusion

Yes, you can invoke the default class implementation from a category on that class. In most cases though, since it is slower at runtime than method swizzling, it is primarily only useful for debugging where 5 lines less code makes it much easier to use.

The speed at runtime is slower than method swizzling because it bypasses cached method lookup. Where cached method lookup takes about 5 nanoseconds on newer machines, this approach takes about 5 microseconds on typical objects with around 50 methods in their hierarchy (slightly slower than uncached method lookup) and like uncached method lookup, it can take longer for classes with very large method tables.

There are a few other limitations as well. This approach will not work on message forwarding classes (like NSProxy) or where other fallbacks are used to handle messages when no method is found. Also, the compiler won't warn you if no supersequent implementation exists or you've passed the wrong number or type of parameters into invokeSupersequent().

Despite these three drawbacks, I still use this approach when I'm debugging. It is just one line to invoke and makes it very easy to replace a method on someone else's class.

Read more...

Testing Core Data with very big hierarchical data sets

I test Core Data's performance with a one million object data set stored in a basic three-tiered hierarchy. I look at the performance when building, loading, fetching and traversing.

The test data

My test data will be a three-tier hierarchy. This arrangement reflects data where containment of one set in another is important. It also creates a situation where graph traversal, searching and containment testing can be performed in more than one way, with no approach being obviously better — leading to a desire for performance testing.

coredatasetentities.png

The following tests will all use the same data:

  • one top-tier object
  • one thousand mid-tier objects, each connected to the top-tier object
  • one million bottom-tier objects, with one thousand connected to each mid-tier object

Each bottom-tier object will have a name with the following format: "Object x, y, z" where "x", "y" and "z" are the index of the top, mid and bottom tiers to which is it connected. This is so that every name is unique and for debugging, I can check that I get the object that I expect.

Building the test document

The following are the times taken to create and save to disk the above described data. Each improvement shown incorporates the previous improvements.

Create methodTime takenPeak memory
Create all objects and save at once368.236 seconds798 MB
As above but invoking setUndoManager:nil on the context first342.618 seconds778 MB
Wrap the contents of the outer loop in an NSAutoreleasePool init/release and NSManagedObjectContext save262.511 seconds254 MB
Invoke NSManagedObjectContext reset after each save258.904 seconds20.1 MB

The different save approaches that I have speed tested are those given by Apple on their Core Data Programming Guide: Efficiently Importing Data page.

Having never created a million object document in Core Data before, I didn't expect document creation to take this long. Taking 4-6 minutes to save a 77.1MB file really didn't seem right. Apple claim that Core Data can cope with terabyte databases; I dread the thought of ever creating one of those.

To determine how slow Core Data is, relative to direct SQLite data creation, I wrote a command line tool to talk to sqlite3 directly and write 1 million rows of data to the ZBOTTOMLEVEL table. This took 124 seconds, so Core Data is roughly doubling the time involved. This is probably reasonable, although it still feels like its taking too long.

Despite my frustration with the length of time, the saving does appear to be highly linear. This table showed a 1 million row database saving in 250 seconds. For 10,000 objects I recorded 2.5 seconds and for 100,000 I recorded 25 seconds and 10 million rows took around 40 minutes (approximately 2,500 seconds).

Out of curiosity, I tried saving the 1 million line document as an XML file. This took 941 seconds, most of which was spent thrashing more than 3 GB of memory around on my computer (which has 2.25 GB of RAM and didn't appreciate the effort). I don't know what all the memory was doing, since the XML file was 227.8 MB and the objects before saving only took around 100 MB of RAM.

The last option (-[NSManagedObjectContext reset]) is particularly inconvenient in an application (since you must refetch every NSManagedObject from the context) but due to its effects on memory useage (12 times less memory than any other technique) it is the only option that would remain usable if you were creating and saving a 20 million row database in this way.

Load the set of all Bottom-Tier object names

My first test will be to build a set of all names of children of Bottom-Tier objects under the Top-Tier objects. This type of action might be done if you are testing names for uniqueness within the hierarchy or if you simply want a list of all the names the hierarchy uses.

I will test by two approaches. First will be an NSFetchRequest with the following NSPredicate:

[NSPredicate predicateWithFormat:@"midLevel.topLevel == %@", topLevelObject];

and then building an NSSet of the "name" keys from each object in the returned array.

Second will be a keyPath fetch:

bottomLevelNames = [topLevelObject valueForKeyPath:
    @"midLevel.@distinctUnionOfSets.bottomLevel.name"];
Fetch methodTime taken (first iteration) Time taken (averaged over 4 subsequent iterations)
NSFetchRequest27.4 seconds15.3 seconds
keyPath access217.1 seconds6.4 seconds
keyPath access after prefetching (which took 13.9 seconds)18.5 seconds 6.4 seconds

Prefetching involved using an NSFetchRequest to return all BottomLevel objects in the database while using setRelationshipKeyPathsForPrefetching: with an array containing "midLevel" to further fetch the MidLevel objects.

Conclusions to draw from this data:

  • NSFetchRequest is the fastest approach for a cold start
  • Using keyPaths on non-prefetched data is extremely slow
  • keyPaths are very fast once cached

I did also test iterating over all the objects in a "for (child in parentChildSet)" approach. This is really a manual form of the "keyPath" approach and unsurprisingly returned almost identical times.

Find a Bottom-Tier object with a specific name

This test will search for the BottomLevel object in the hierarchy, with a specific "name" value.

I will perform this test in 4 different ways:

  • As before, one search approach will use an NSFetchPredicate to perform the work, with no database field indexed.
  • A second search will also use an NSFetchPredicate, this time with the "name" field on BottomLevel indexed.
  • A third approach will compare this with the most naive approach: a manual traversal of the entire object graph looking for the BottomLevel object with the given "name".
  • Finally, I will try to cache the lookup by generating mapping in the TopLevel object which maps from "name" values to the BottomLevel object with that value in the hierarchy and compare this cached lookup to the other approaches.

Both NSFetchRequest tests will use the following NSPredicate:

[NSPredicate predicateWithFormat:
    "midLevel.topLevel == %@ AND name == 'Object 5, 5, 0'", topLevelObject];

The manual traversal will traverse over all objects and test the name for equality with @"Object 5, 5, 0". Since manual traversal can exit as soon as it finds a match, I will base my timing on matches found after exactly 500,000 comparisons (which should offer an appropriate average).

The cached mapping of "name" values to BottomLevel objects will be a NSDictionary built as follows:

NSSet *bottomLevelSet = [topLevelObject
    valueForKeyPath:@"midLevel.@distinctUnionOfSets.bottomLevel"];
NSArray *bottomLevelArray = [bottomLevelSet allObjects];
NSArray *bottomLevelNames = [bottomLevelArray valueForKey:@"name"];
NSDictionary *bottomLevelKeyedByName =
    [NSDictionary
        dictionaryWithObjects:bottomLevelArray
        forKeys:bottomLevelNames];
Fetch methodTime taken
NSFetchRequest (no indexing of 'name')670,000 microseconds
NSFetchRequest (with 'name' indexed)2,174 microseconds
keyPath traversal (average after prefetching)940,000 microseconds
NSDictionary (after setup of 12.6 seconds)24 microseconds

The keyPath traversal only needs to traverse until it finds the value it wants. I deliberately searched for a non-existent value (forcing full traversal) and halved it to get this average value.

After I ran these tests, I tried an NSFetchRequest without the hierarchic constraint (using the predicate format string: @"name == 'Object 5, 5, 0'"). This approximately halved the time taken but showed that a JOIN is not as catastrophic as forgetting to index a search field.

Conclusions from this data:

  • NSFetchRequest is predictably fast on this type of lookup.
  • It is really important to index fields (using the checkbox in the XCode Data Model editor). Without this, SQLite manually searches every element and is almost as slow as a full traversal.
  • Iterating over a million string comparisons is much faster than I expected but still not as fast as having an indexed lookup
  • Nothing gets close to NSDictionary (once it is setup). It is 100 times faster than an SQL indexed lookup. This is unsurprising since it is a data structure designed specifically for this type of lookup.

Final conclusions

Core Data is not a panacea for all data management ills. It does not make everything magically fast. Obviously, there are still areas where it can be slow (sometimes very slow) and there are data access approaches which must be avoided.

NSFetchRequest does what it should and does it quickly. Provided you index your search fields.

It seems like NSSQLStore could save a little faster. 4-6 minutes to save a 77.1 MB document doesn't seem right. However, it isn't an order of magnitude slower than bare SQLite and it's still faster than NSXMLStore or NSBinaryStore for anything bigger than trivial sizes.

Basic iteration over cached Core Data objects works surprisingly well given how much work is being done. Millions of keyPath accesses and millions of string comparisons happen within a second — not significantly slower than SQLite's optimised version of the same when searching without an index.

Read more...

Construct an NSInvocation for any message, just by sending

I will show you how to use object forwarding to record any message in an NSInvocation, by simply sending the message to an object. Unlike techniques shown elsewhere, this will allow you to record any message, including NSObject messages and even the forwarding messages themselves.

NSInvocation is painful to construct

This article appears to be the second in an ad hoc series I'm writing on Cocoa. If it is, then series title might be something like:

Doing tricky things simply in Cocoa with one line of code

I refer you to my earlier post Core Data: one line fetch where I show a single line fetch for Core Data instead of the suggested 10 line common approach.

NSInvocation has a very similar problem where the its shortest possible usage case using the default methods is 4 lines and the common case is closer to 6.

So, I'm going to reduce that to 1 (compound) line and make the code conceptually cleaner too.

Creating an NSInvocation using the default methods

According to Apple's documentation on the page Distributed Object Programming Topics: Using NSInvocation, to create an invocation for the MyCalendar method:

– (BOOL)updateAppointmentsForDate:(NSDate *)aDate

with a target and argument respectively of:

MyCalendar *userDatebook;    /* Assume this exists. */
NSDate *todaysDate;          /* Assume this exists. */

will require the following code:

SEL theSelector;
NSMethodSignature *aSignature;
NSInvocation *anInvocation;
 
theSelector = @selector(updateAppointmentsForDate:);
aSignature = [MyCalendar instanceMethodSignatureForSelector:theSelector];
anInvocation = [NSInvocation invocationWithMethodSignature:aSignature];
[anInvocation setSelector:theSelector];
[anInvocation setTarget:userDatebook];
[anInvocation setArgument:&todaysDate atIndex:2];

This isn't the largest or most cumbersome block of code but it does seem a little large for packaging a method invocation.

Obviously, you could pass just theSelector, the target userDatebook and all the arguments (in a nil terminated variable argument list) through to a constructor method. I've seen this approach used before. It tidies the code up a lot, but it makes the assumption that none of your arguments are nil. It also makes a cumbersome, unstructured, method invocation.

Message forwarding

To spoil the ending for you, I'm going to show you a way to cut all this code down to one line. Like so:

NSInvocation *anInvocation;
[[NSInvocation invocationWithTarget:userDatebook invocationOut:&anInvocation]
    updateAppointmentsForDate:todaysDate];

The biggest advantage to this approach is that you are sending the updateAppointmentsForDate: message as normal, with parameters.

Now, this is not the most revolutionary concept. The designers of Cocoa use a similar, but more limited, technique in the NSUndoManager class. From Apple's Undo Architecture: Registering Undo Operations:

[[myUndoManager prepareWithInvocationTarget:drawObject]
    setFont:[drawObject font] color:[drawObject color]];

This is a 1 line reduction of NSInvocation creation for the message:

[drawObject setFont:[drawObject font] color:[drawObject color]]

The NSInvocation isn't returned to the calling function (it's held internally by NSUndoManager) but it is creating this NSInvocation for its own internal use, just by recording the unhandled message.

It relies on the Objective-C methods:

  • - (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
  • - (void)forwardInvocation:(NSInvocation *)anInvocation

to capture any message sent to an object which the object does not handle itself and save the parameter anInvocation.

This is a very good solution but it can't handle every situation. It only lets you capture those messages that the object does not already handle. NSUndoManager is unable to handle NSObject instance methods and any NSUndoManager instance method.

For example, NSUndoManager cannot create an NSInvocation of:

  • init
  • class
  • release

or any other NSObject or NSUndoManager method since it already has methods for these. Even if we were to create a non-NSObject derived class, it still wouldn't be able to create an NSInvocation for:

  • methodSignatureForSelector:
  • forwardInvocation:

using this approach because the forwarding system can't automatically catch and forward its own methods.

How to capture any message

The trick to capturing any message is to send the message for capture to an object which only responds to:

  • - (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
  • - (void)forwardInvocation:(NSInvocation *)anInvocation

and for those two methods, the object must be able to distinguish between a forwarded message (where the parameter anInvocation just needs to be saved) and a message sent directly to those methods (for which an NSInvocation must be manually constructed).

By distinguishing forwarding from invocation in those two cases, we will be able to build an NSInvocation for absolutely any valid message.

Approach

To summarize all steps, we need:

  1. A base class (one which doesn't inherit from any other class)
  2. Only instance methods are:
    • - (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
    • - (void)forwardInvocation:(NSInvocation *)anInvocation
    all other work must be done through class methods.
  3. An approach to distinguish a message forwarded through methodSignatureForSelector: from a direct invocation of methodSignatureForSelector:
  4. An approach to distinguish a message forwarded through forwardInvocation: from a direct invocation of forwardInvocation:

Steps 1 and 2 are straightforward class construction. Allocating a base class is a bit unusual but not very hard.

Step 4 can be done by checking if the "target" of the anInvocation parameter is equal to the self parameter inside the method. If it is, then it's a direct invocation, otherwise it's a forwarded message.

Step 3 is trickier. The parameters passed are no different for a regular invocation to a forwarded invocation. Instead, we need to be get little dirtier. We can deliberately pass an unhandled message (which will go through the forwarding code) in a controlled situation and record the return address. By recording the known return address into the forwarding code, we can thus distinguish subsequent forwarded invocations from direct invocations. The return address can be obtained using a gcc built in function that I've used before, __builtin_return_address(0).

Of course, there's no absolute guarantee that multiple paths through the forwarding code (which would result in different return addresses) won't happen. For this reason, we'll use an approach that is tolerant of mistakes. Since forwardInvocation: is always called after methodSignatureforSelector: for forwarded invocations, then we can correct false direct invocation determinations afterwards by overwriting their result.

Solution

We have a category with the following structure:

@interface NSInvocation (ForwardedConstruction)

+ (id)invocationWithTarget:(id)target
    invocationOut:(NSInvocation **)invocationOut;
+ (id)retainedInvocationWithTarget:(id)target
    invocationOut:(NSInvocation **)invocationOut;

@end

Those are our entry and exit points in one. The invocationOut parameter is only set after the message to be recorded is sent.

The id returned is actually an instance of the following class:

@interface InvocationProxy
{
    Class isa;
    NSInvocation **invocation;
    id target;
    BOOL retainArguments;
    NSUInteger forwardingAddress;
}

+ (id)alloc;
+ (void)setValuesForInstance:(InvocationProxy *)instance
    target:(id)target
    destinationInvocation:(NSInvocation **)destinationInvocation
    retainArguments:(BOOL)retain;
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector;
- (void)forwardInvocation:(NSInvocation *)forwardedInvocation;

@end

This is our special base class. It handles it own alloc. It also requires that init be sent to it after allocation (even though the class doesn't implement init) to record the return address for message forwarding.

The setValues... method configures the instance so that the next message sent to it will have its invocation recorded and store in destinationInvocation and the two instance methods methodSignatureForSelector: and forwardInvocation: perform the work of capturing the forwarded message as earlier described.

There's also another privately declared class in the implementation named DeallocatorHelper. This class is used because InvocationProxy doesn't have an autorelease, release or dealloc method but needs to be freed by the NSAutoreleasePool. Instead we create and autorelease the DeallocatorHelper which then deallocates the InvocationProxy in its own dealloc method. This code is all #ifdef'd out when compiled under garbage collection.

Conclusion

Get the code here: NSInvocationForwardedConstruction.zip (4kb)

It will let you create an NSInvocation as follows:

NSInvocation *anInvocation;
[[NSInvocation invocationWithTarget:target invocationOut:&anInvocation]
    methodParam1:argument1
    methodParam2:argument2
    methodParam3:argument3
    methodParam4:argument4];

for any method with any number of and type of parameters and any valid value of arguments. Invoking retainedInvocationWithTarget:invocationOut: if you want to retain the arguments of the NSInvocation.

If want to create an NSInvocation for a selector (for example aSelector) instead of a method, with known arguments, you can invoke as follows:

NSInvocation *invocation;
id proxy = [NSInvocation invocationWithTarget:target invocationOut:&invocation];
objc_msgSend(proxy, aSelector, argument1, argument2, argument3, argument4);

You will need to use objc_msgSend_stret or objc_msgSend_fpret instead of objc_msgSend for methods returning structs or doubles respectively.

Read more...

Cocoa Application Startup

How does a Cocoa Application start up? Where are the main places to put code so that it gets run on startup? Learn the answers in this series of startup diagrams.

The natural first question

After working through the first Cocoa tutorials and learning how to hook up basic methods to buttons and menus, the most common question I hear from new Cocoa programmers is:

Where do I put my code so that it runs when my Cocoa Application starts up?

Cocoa makes it very easy to edit and connect things in Interface Builder but you quickly reach the limits of this simple program setup. Documents and application windows can magically appear but eventually you'll want to have control over these default operations.

Once you need to do more, you need to start piercing through the magic of Cocoa Application startup and understand what the NSApplication does, how the Interface Builder NIB files appear and how to run customization code for documents and other elements.

Questions about how program startup works are the right questions to ask — you need to control your program and make it your own. This starts at the very beginning. But it can be tricky to decide where to put your code: Cocoa gives you many different places to initialize different components so that appropriate setup is performed in the appropriate place. I'm going to show all the common places in a Cocoa Application where code is run on startup. With luck, knowing the options will help you choose the right one.

Objective-C runtime initialization

The Objective-C runtime offers places to initialize your classes during its startup, as the following diagram shows:

startupMain.png

The main() method works in Objective-C as it would for any standard C program and you can perform global initializations here if you want. Typically though, Cocoa Applications do nothing here except invoke NSApplicationMain(). The reason for largely ignoring this entry point is that classes, application instances, documents and user interface elements have their own means of initializing themselves and it makes more sense to use these locations.

Traditionally, in C languages, main() is the earliest place where you can perform startup and initialization. In Objective-C, the first initialization offered occurs even earlier than this: +(void)load methods. Any class can have a +(void)load method and it will be invoked by the runtime when the class is loaded. For normal compiled classes, this occurs during "image loading" (some time before main() is invoked). Since classes are loaded in no particular order and other classes may not yet be loaded, you must be careful what you do here — generally, you shouldn't refer to other classes in +(void)load methods.

Objective-C also provides a similar (but safer since you can refer to other classes) setup method: +(void)initialize. This is the most common place for performing class-specific setup. Before a message is sent to an object of a class for the first time, +(void)initialize is sent to the class and all its super classes (if they haven't been initialized already). These messages are sent in hierarchical order (super classes receive the message before descendant classes). While safer (because all classes are loaded by this point) the timing of its invocation is less deterministic since +(void)initialize is only invoked when a first message is actually sent to the class — if a class is never used, the message is never sent.

NSApplication initialization

Here is the typical startup for NSApplication (as invoked through NSApplicationMain() in the previous diagram):

startupNSApp.png

This image shows the application (normally NSApplication but this is configurable in the Info.plist file) being initialized and run. Despite the fact you can change the principal class of your application, it is advised that you don't — so this isn't the first place to consider putting startup code.

Instead, you should look towards the three main functions that the application performs on startup (load main NIB, load first document, notify NSApplication delegate). These are the key areas to hook into.

An NSApplication is only considered to handle documents if CFBundleDocumentTypes is configured in the Info.plist file. Without this value in the Info.plist, the NSApplication will skip document handling (non-document applications).

The first of these areas to consider is the "main NIB" file. A NIB file is the standard user-interface file and it is created in Interface Buillder. The "main NIB" is the user-interface file that normally contains the menubar and other "on startup" resources. It is also the common location for the NSApplication delegate. If you don't know what a delegate is, you can read Apple's description of delegates but it's really any object that is connected to the NSApplication by its "delegate" outlet (usually in Interface Builder). The delegate is special because NSApplication sends it messages in response to certain events. These are the delegate methods.

At startup, the NSApplication delegate receives one of its most important messages, applicationDidFinishLaunching:. Almost every application implements this method. It is the best place to fix program-wide settings after everything has been created and loaded.

If you need something more specific to a window or document to be initialized, then you'll need to hook into one of the other steps. If you're writing a non-document application with a single fixed window, then it will likely be loaded along with the main NIB, so you'll want to read the next section about NIB loading. If you are writing a document application, you'll want to look at the document loading section.

NIB loading

An Interface Builder NIB file is loaded as follows:

startupNib.png

Application windows, document windows, the menubar and the NSApplication delegate are all typically loaded from a NIB file in this fashion.

The point to note here is that your objects' init methods are invoked before their IBOutlet connections are configured according to the settings in the NIB file, so you can initialize your own object but you can't yet read objects connected through Interface Builder.

For this reason, the a common way to initialize an object loaded from a NIB file, is to implement the -(void)awakeFromNib method on the object. If this method is present on an object, the NIB loader will invoke it after the whole NIB is initialized and connected, making it the perfect place to perform configuration involving multiple objects.

Document loading

A document is loaded as follows:

startupDocument.png

The key places to initialize a document are: its init methods, in the loading of the document's NIB file and in windowControllerDidLoadNib:. Simply put, these offer configuration locations for before, during and after loading of the document's window resources.

Conclusion

I have not shown every location you can use on startup. There are many more delegate methods, notifications and overrideable methods if you have genuine need of them. What I have shown are the most common and most useful locations.

These locations are:

  • +(void)initialize
  • -(void)awakeFromNib
  • -(void)windowControllerDidLoadNib:
  • -(void)applicationDidFinishLaunching:

as well as the usual init methods for your own subclasses.

Know what each of these methods are, when they are invoked and understand objects for which they are responsible. They will let you perform almost all configuration on Cocoa application startup.

Read more...

Break into Debugger

For your debugging pleasure: a DebugBreak() macro to programmatically stop the debugger at a line of code (not inside a child function). Some of this code can be found elsewhere but I present it here, PPC and Intel capable and ready to run.

Updated July 31, 2008: Fixed assembler statements so that they work again.

Why programmatically stop the debugger?

If you're debugging and you have consistency checks in your code, sometimes you can just log any errors to the console. But there are other times when you want to enter the debugger and explore the memory yourself. Maybe you want to explore the state of your variables to find why things have gone wrong. Maybe any debug information would get lost in your console output.

To allow this, you need a command which will stop GDB at the current line of code. Microsoft's Visual Studio has a handy DebugBreak() command to do just this. On Mac OS X, we get Debugger() and DebugStr() but these don't stop the debugger at the line which invokes them, they instead break the debugger deep inside their own contents.

How do you stop GDB anyway?

GDB will stop if it encounters a SIGINT (an interrupt signal). There are all kinds of ways to send a SIGINT — pthread_kill() is a good example — however performing this inside a function call has a disadvantage: the debugger will be inside the function which sends the SIGINT when it breaks, not at the line of your code where you called it.

Inline assembly

The way around this stack issue is to invoke the sys_kill system call or int machine instruction (depending on your CPU) directly inline in your code using inline assembler. That way, the stack doesn't increase and your function is still on the top when you enter the debugger.

The code

Language note:
Most code in this blog is Objective-C only but the following code should compile in any of C, Objective-C or C++ under GCC.

Here's the code to do it. Put it in a header somewhere. Maybe even include the header in your .pch (precompiled header) file.

#ifdef DEBUG
    #if __ppc64__ || __ppc__
        #define DebugBreak() \
            if(AmIBeingDebugged()) \
            { \
                __asm__("li r0, 20\nsc\nnop\nli r0, 37\nli r4, 2\nsc\nnop\n" \
                    : : : "memory","r0","r3","r4" ); \
            }
    #else
        #define DebugBreak() if(AmIBeingDebugged()) {__asm__("int $3\n" : : );}
    #endif

    bool AmIBeingDebugged(void);
#else
    #define DebugBreak()
#endif

You'll also need to copy AmIBeingDebugged() from Apple's Technical Q&A QA1361 Detecting the Debugger and put it in a source file (not a header) somewhere. It's a good idea to put #ifdef DEBUG and #endif around that code too.

If you don't have a DEBUG preprocessor macro defined (you really should) you'll also need to set it up.

  1. Right-click on your target (normally same name as your project or executable but it's under the "Targets" heading in the tree view in XCode).
  2. Select "Get Info" from the context menu that pops up.
  3. Go to the "Build" tab.
  4. Make sure the "Configuration" is set to "Debug".
  5. Type DEBUG into the field next to "Preprocessor Macros" under "GCC 4.0 - Preprocessing".

What does the code do?

First: it does nothing outside of DEBUG, that's important. Then it invokes AmIBeingDebugged() to check if GDB is actually running (just because you have the Debug build, doesn't mean GDB is running). Then comes the assembly.

On Intel machines, it's easy: "int $3" (send a SIGINT interrupt to the current process).

On PPC platforms, there's more to do (RISC is more wordy than CISC). Relevant PPC assembler information:

  • "li" - load integer, puts the second argument into the location specified by the first
  • "sc" - system call, invokes the UNIX system call indicated by the integer in register zero with other arguments starting at register 3.
  • "nop" - No operation. Required to wait for some operations to complete.

So here's what the PPC assembly code does:

  1. loads 20 into register 0
  2. makes a system call, which will be call "20" (sys_getpid) which returns the process ID of the current process into register 3.
  3. wait for "sc" to complete
  4. loads 37 into register 0
  5. loads 2 into register 4
  6. makes a system call, which will be call "37" (sys_kill) which sends the signal identified by the integer in register 4 (2 = SIGINT) to the process with ID specified by register 3 (our own PID as returned from the last system call).

If you're wondering what the : : : "memory","r0","r3","r4" stuff is all about, it's just telling the compiler that the assembly block may alter the contents of "memory" and registers 0, 3 and 4.

Read more...

Core Data: one line fetch

It's a lot easier to get your data out of Core Data than the documentation will tell you. This simple 1-line fetch will work just as well as Apple's suggested 10-line approach for most uses.

What does Core Data do?

The Core Data documentation avoids giving a simple explanation of what it does. I'm going to help them out.

Core Data holds onto your data for you.

Lets make the assumption that it holds the data very well. Fair assumption, it's a pretty good API. Once that's done, what would a typical programmer like to do next? I think the following is fair:

A typical programmer would like to get their data back again.

Wow, what a revelation! I think this could catch on. Programmers might even want to do this all the time.

Fetching data, according to Core Data

It's a very common task. A good API should have a nice simple option for doing this. Let's look at what Core Data suggests. According to the Core Data Programming Guide:

NSManagedObjectContext *moc = [self managedObjectContext];
NSEntityDescription *entityDescription = [NSEntityDescription
    entityForName:@"Employee" inManagedObjectContext:moc];
NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
[request setEntity:entityDescription];
 
// Set example predicate and sort orderings...
NSNumber *minimumSalary = ...;
NSPredicate *predicate = [NSPredicate predicateWithFormat:
    @"(lastName LIKE[c] 'Worsley') AND (salary > %@)", minimumSalary];
[request setPredicate:predicate];
 
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc]
    initWithKey:@"firstName" ascending:YES];
[request setSortDescriptors:[NSArray arrayWithObject:sortDescriptor]];
[sortDescriptor release];
 
NSError *error = nil;
NSArray *array = [moc executeFetchRequest:request error:&error];
if (array == nil)
{
    // Deal with error...
}

Really, Core Data designers? Really? It's a common task, programmers need to do it all the time, essential for using Core Data and it requires 13 lines for the most common single task?

One line, thanks

I think they got it wrong. All of the above code should be reduced to:

[[self managedObjectContext] fetchObjectsForEntityName:@"Employee" withPredicate:
    @"(lastName LIKE[c] 'Worsley') AND (salary > %@)", minimumSalary];

That line would perform all the work of the previous code monstrosity except sorting which would still be a separate step, if needed. 10 lines, down to 1 through providing a better method for the common case.

Obviously, looking up the Entity and building the NSPredicate each time isn't going to be the optimal fast case and other special NSFetchRequest options aren't accessible, but for most other cases, 10 times shorter equals 10 times better.

You'll also realise that since we've removed sorting, all of the objects returned are unique and in no particular order. This is an NSSet, not an NSArray and the return type has been changed accordingly. Creating an NSSet has a slightly higher overhead than creating an NSArray but again, we're considering quick and simple fetches and this approach allows easy testing of set membership in the results (a very useful logic case).

Make it so

A good thing about Objective-C is that limitations in the default API are no real hinderance. Put the following in a NSManagedObjectContext category and all these wonders can be yours.

// Convenience method to fetch the array of objects for a given Entity
// name in the context, optionally limiting by a predicate or by a predicate
// made from a format NSString and variable arguments.
//
- (NSSet *)fetchObjectsForEntityName:(NSString *)newEntityName
    withPredicate:(id)stringOrPredicate, ...
{
    NSEntityDescription *entity = [NSEntityDescription
        entityForName:newEntityName inManagedObjectContext:self];

    NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
    [request setEntity:entity];
    
    if (stringOrPredicate)
    {
        NSPredicate *predicate;
        if ([stringOrPredicate isKindOfClass:[NSString class]])
        {
            va_list variadicArguments;
            va_start(variadicArguments, stringOrPredicate);
            predicate = [NSPredicate predicateWithFormat:stringOrPredicate
                arguments:variadicArguments];
            va_end(variadicArguments);
        }
        else
        {
            NSAssert2([stringOrPredicate isKindOfClass:[NSPredicate class]],
                @"Second parameter passed to %s is of unexpected class %@",
                sel_getName(_cmd), [stringOrPredicate className]);
            predicate = (NSPredicate *)stringOrPredicate;
        }
        [request setPredicate:predicate];
    }
     
    NSError *error = nil;
    NSArray *results = [self executeFetchRequest:request error:&error];
    if (error != nil)
    {
        [NSException raise:NSGenericException format:[error description]];
    }
    
    return [NSSet setWithArray:results];
}

Keen coders will notice that the second parameter can be an NSPredicate or an NSString, allowing a little extra lazy freedom there if needed. It was a spur of the moment choice which seemed convenient, I'll decide later if it constitutes bad design.

Read more...

Polymorphism is always the wrong term

Explaining the term "polymorphism" is common question in job interviews, exam questions and books on object-oriented programming and design. I'm bothered by this because the term is so abstract as to be worthless. There is no implementation that is best described as "polymorphic" — actual implementations always use more specific terms, leading to a situation where "polymorphism" is only ever used in theory and only serves to obfuscate and confuse. In this post, I'll look at why I think the term is too vague and which more specific terms are typically used instead.

Book learning

polymorphism (noun) theory, programming
A term used to describe a variable that may refer to objects whose class is not known at compile time and which respond at run time according to the actual class of the object to which they refer.
The Free On-line Dictionary of Computing

If you've ever studied object-oriented design, then you have probably noticed that one of the first definitions taught is that of "polymorphism". Perhaps you think this is reasonable; afterall, polymorphism can be used to explain many traits of object-oriented languages.

For example, in Objective-C code where a single message is sent to an object, any object which responds to the message's selector can be exchanged for any other object that responds to that selector at runtime. The completely dynamic nature of Objective-C method lookup means that Objective-C is one of the most "polymorphic" of all compiled languages.

Programmers don't use the term

Given the broad scope for potential use, it may seem strange that few programmers ever really use the term "polymorphism". In fact, if you ever hear a programmer using the term, they're likely only doing it to try to sound like an execu-speak-bot. "We'll proactively synergize our existing product with technologies leveraging polymorphism!"

The reality is that "polymorphism" is never the most accurate description of why something is done. Since there is no single case where it is the best description, it ends up never getting used. Instead, the terms that programmers use are the terms that describe actual implementations.

Polymorphism is an ontological classification of a handful of different programming techniques that may substitute one type for another. But type substitution is never the end-goal in these situations, instead the type substitution is an artefact of an implementation that is trying to achieve a specific design or behavioral goal that is not itself correctly called polymorphism.

Let's look at some of these design goals and see the actual terms used to describe them.

Method overriding

The canonical example of polymorphism given by most textbooks goes by another, far more common name: method overriding.

MyBaseClass *newObject = [[[MySubClass alloc] init] autorelease];
[newObject instanceMethodDeclaredInMyBaseClass];

In this example, when instanceMethodDeclaredInMyBaseClass is invoked, it could be the base implementation or it could be an override defined in the subclass — the distinction has no impact on how we invoke the method nor does it impact on the type of the variable newObject. The only determining factor is whether the MySubClass class overrides this method from the base class.

No one would ever describe this by saying: "here we polymorphically invoke the base or subclass method".

Instead, we always describe this more accurately: "here we invoke a method which the subclass may have overridden".

override noun
An alternate implementation of a method on a subclass so that instances of the subclass may substitute different behaviors for the method relative to the base class.

subclass noun
An alternate implementation of the interface of a base class. The subclass represents a more specific version of the more general base class by adding extra data and methods to the definition but retaining all data and methods from the base class.
By retaining the same data and set of methods, a subclass object is normally interchangeable with a base class object and can be indistinguishable without runtime type information.

Since subclasses and method overrides are so fundamental to object oriented design and implementation, these terms are the most informative and most familiar to all relevant audiences. Sometimes extending, deriving or (more broadly) inheritance can be used to describe the situation (depending on why the subclass was created and how the sentence is worded) but again, these are terms related to the design principles involved.

The term polymorphism implies that we might have switched an unrelated object into the place of the expected type. That isn't what inheritance hierarchies do. While there is more to newObject than just MyBaseClass, it is also a MyBaseClass instance. This is why the following code:

[newObject isKindOfClass:[MyBaseClass class]]

returns YES if object is a MyClass or a MySubClass. MySubClass has all the same data as MyClass and all the same methods.

Yes, there is a mechanism that resolves a message sent to an object and invokes the correct implementation for the specific runtime type of the object. In Objective-C, this is the "messaging system". The equivalent in C++ is the vtable. You will never hear anyone call this the "polymorphism system" or the "polymorphic abstraction layer".

A collection of objects, where the type of the object is unimportant

In Objective-C, objects of type id are frequently used by collections classes (NSArray, NSDictionary, NSSet, etc) because these collection classes don't care what objects they are handling.

NSArray *array = [NSArray arrayWithObjects:someObject, someOtherObject, nil];

This usage does count as "polymorphism" because the exact class of someObject and someOtherObject doesn't need to be known at compile-time.

Most of the time, a programmer will simply say: "NSArray takes objects of type 'id'", and leave it at that. This is literally what happens; it is the best description.

If pressed for a more abstract description, the best term is actually:

generic programming
A style of computer programs where a part of the program is left variable or unknown, to be filled in at a later date.

Generic programming states that the code has been written to allow any object or, in the case of NSArray, any "first class" or NSObject. In contrast to the implied polymorphic case where the code is written to expect type "X" and you are expected to provide something that behaves like type "X", generic programming implies that the code doesn't care what type it is given and won't place any significant requirements on the type.

Using the term "generic" also relates this useage to other languages and setups where the generic use isn't polymorphic. For example, collections programming in C++ for the previous example might look like this:

std::vector<MyClass> array;
array.push_back(someMyClassObject);
array.push_back(someOtherMyClassObject);

This is still called "generic" programming. The definition of Class std::vector<T> doesn't know about MyClass, yet it's not really polymorphic because the type is known at compile time. C++ generic programming gets the type when the object is declared not when the Class is defined.

Unrelated substitutions

There is a final polymorphic case in Objective-C. There are extremely rare situations in Objective-C where an object of one class might be substituted with an object of an unrelated class. This isn't easily possible in less dynamic languages like C++ but the dynamic binding of selectors to method implementations in Objective-C permits some unique design solutions.

Examples of this type of solution include:

  • NSProxy, which receives messages on behalf of another object at the other end of an NSConnection.
  • NSKeyValueObserving constructed classes which intercept messages to Observed objects through "isa" swizzling so that NSKeyValueObserving notifications can be sent when data setting messages are received.
  • Invoking a specific method, with no regard for the class or type. In Objective-C, this includes most informal protocols, including many delegate methods.

In these cases, the Objective-C messaging system is being extended. In the NSProxy case, the messaging system is extended to send messages to a remote location. In the NSKeyValueObserving case, it is extended to perform extra work when certain messages are received.

Since these cases involve the substitution of an unrelated class, they are the most deserving of the term of all the cases explored so far. Scour the documentation on them however, and you'll find that they are never described as such.

The reality is that these classes represent very special cases in programming. Due to their peculiarities, it is important to be specific about the design philosophy employed.

proxy (pattern)
an object of one class functioning as an interface to a different object, possibly of a different class

NSProxy explicitly notes its design approach in its name. Specifically, NSProxy is a "Remote Proxy".

NSKeyValueObserving constructed classes are always noted as "isa" swizzling — an Objective-C specific implementation approach used specifically to extend the messaging system. In essence, this approach wraps the observed class in another class which sends NSKeyValueObserving notifications when appropriate before invoking the underlying class' methods.

While this could be argued as being a "smart proxy" (a proxy object which performs tracking actions as references or messages to the underlying object are made or sent), wrapping objects which add runtime behavior are normally called "Decorators".

decorator (pattern)
an object of one class wrapping an object of another class at runtime, where the outer object exposes the same interface as the inner object.
This wrapping is done to introduce additional functionality to the inner object's interface.

A final type of unrelated object usage are methods sent to an object, regardless of the type. We can do this safely in Objective-C by asking an object if it handles a specific message (using respondsToSelector:) and only send the message if the object will handle it.

This type of introspective method invoking falls under the larger banner of duck typing.

duck typing (dynamic typing)
a situation where you send a message to an object of unknown type, but where you assuming the object will handle the message, and let the object decide how to respond to the message in its own way. From the informal test: if it looks like a duck and quacks like a duck, then it is a duck.

Duck typing revolves around the idea that an object need not have a type. Instead, objects need only claim to adhere to a certain model. Once an object claims to adhere to a model, then you can operate with it within the bounds of that model.

Often with duck typing, the fact that the programmer has used a variable in a certain context means that the programmer is asserting it will work within that context. In Objective-C, this approach was typically described using informal protocols (declared categories on NSObject that had no generic implementation) and more recently by optional protocols.

Conclusion

Polymorphism's use as a term is fundamentally limited by how vague it is. It does not describe a particular model or a particular implementation; instead, every implementation which could fall under the greater banner of polymorphism has a description which is more specific and better understood because of this.

The reality is that there is no real situation where the term "polymorphism" aids understanding of an implementation. Given this, the term has no real value to programmers.

Interviewers and examiners: please ask relevant questions instead; stop torturing already stressed programmers by asking them to explain purely abstract terms that they will never need to use. Authors: please use relevant terminology in books. Certainly don't begin explaining the term "object oriented" to beginners by first describing "polymorphism" as the fundamental underlying mode of operation. Programming theory is dry and dull enough already.

Read more...