Incrementing paths

I've added a new feature to KSFileUtilities: -[NSString ks_stringByIncrementingPath]

What's this for? It helps with the fairly common pattern of building up a path, trying to find the best available. You don't want to overwrite an existing file if it exists, but instead find another path, as similar to the first as possible.

Perhaps best described by a simple example:

Let's say you passed in @"foo.png" as the filename, if that wasn't available -ks_stringByIncrementingPath will return @"foo-2.png". Followup calls will give @"foo-3.png", @"foo-4.png", and so on.

Isn't that great? No need to worry about tracking the base path and count in use. It's all handled internally for you.

How's this work? Internally -ks_stringByIncrementingPath performs a little magic. It returns a special NSString subclass that tracks the path number in use, so that future calls correctly increment it. Check out the source if you want to see how it works!

I imagine this won't meet everyone's needs. Perhaps you want a different separator string, or to apply the same logic to URLs. If so let me know on GitHub and I'll look into it.

NSTreeController has lousy KVO performance

It's time once again for me to try and justify my use of NSTreeController. Or more realistically, show how to work around its flaws.

The latest problem I hit was one of performance. In Sandvox we have a tree controller setup for the site outline. A whole bunch of controls from both the document window, and the Inspector are bound to its selection. e.g. @"selection.title"

This seemed to be working great, until we discovered a site with a blog containing a few hundred pages. Expanding the blog to show its contents in the site outline would beachball the app for several minutes. What was going on here?

Well, after some poking around in the debugger, it seems that when you observe a selection key path — e.g. by binding to it — NSTreeController implements that by observing the key path on every single content object. So exposing 100 new objects to the tree controller, means 100 new KVO observers added. And that's just for a single key path; Sandvox's Inspector observes dozens!

Hmm, what to do? Well, here's the solution I hit upon:

NSTreeController has lousy KVO performance

Give the Inspector its own array controller and bind all the controls to that. The array controller in turn is bound to @"selectedObjects" of the tree controller, with NSSelectsAllWhenSettingContentBindingOption.

The result is that the model objects are only being observed by the inspector controls when actually selected, as desired.

Update: Richard Somers points out to me that Apple has recommended this sort of approach at WWDC before. It’s covered in “Session 136 – Getting the Most Out of Cocoa Bindings” from WWDC 2005, which was available from Developer on iTunes when I grabbed it a few days ago, but now seems to have gone missing.

Unit Testing KSFileUtilities

Those of you keeping an eye on KSFileUtilities, will probably have already noticed that the project recently gained a branch for unit testing. For those of you not, well, you've just been told.

Many thanks go to friend of mine, and NSCoderNight London organiser, Abizer Nasir, for getting the system set up.

So far we're only testing the -[NSString ks_pathRelativeToDirectory:] method. I certainly plan to add more in the future, but for now this is pretty good since it's the most error-prone method in the library, and the foundation of -ks_stringRelativeToURL:.

Of course if you have a little spare time, adding some tests of your own is much appreciated. See the README for instructions on how the repo is laid out.

Four years

So, uh, last year I may have promised that’d we, you know, release some stuff. (Seriously, a year? How’d that happen?!). And, well, still no Sandvox. But let’s give it a few more days shall we?

Update:

Of course, Sandvox 2 is now shipping. I don’t think I can really describe how much effort I’ve put into building this the last two years. Go get it.

© Mike Abdullah 2007-2012