Mac: Carbon vs. Cocoa: Keeping track of those Pesky Things Called FREFs, aka Files
In keeping with our theme of debating the "moderne" nature of Cocoa, today we pit the venerable, 30yr old Unix ASCII pathname, updated in the mid-90s with UTF-8 for the non-english speaking world, against the 10 year old, Carbon, FSRef opaque data type. Wirth would call it an Abstract Data Type
. Unix paths are used in OSX and Cocoa (primarily) to represent just about everything. Until the advent of the URL (another ASCII bitch-slap), unix paths were all powerful. Unix was designed to allow everything to be addressed through the hierarchical database which was/is the file system. Everything was a file, even things like SCSI devices. And because everything is a file, the unix pathname could be used to address any resource in the OS.
Despite the fact that Mr. Jobs took some of his best engineers with him to start NeXT, clearly there were and are plenty of good minds at Apple, both during the split and after. Today's Finder is hardly related to the NeXT workspace manager, and it ain't no descendent of the Mac OS 9 Finder either. Despite the fact that the OS9 Finder was running on something of a weak (by everyone's reckoning at this point) OS foundation, it was chock-full of the best UI design principles. I'm not talking about eye-candy here, but things that really matter.
Cocoa developers who have never written an application against the MacOS toolbox will be forever impoverished by their lack of experience. FSRefs are relatives to the unix path. They are used by Carbon programmers to address objects in the file system. Hence F
eference. They can address any existing
object in the file system. If an object does not yet exist, it can be addressed using a FSRef parent (ie. containing folder/directory) in combination with a UTF-16 pathname which represents the latent part of the name.
Yawn says the Cocoa/unix programmer. Yawn on little doggie, says I.
Today I have a bunch of digital photos sitting on my desktop. A variety of sources. Internet, digital camera, my favorite porn site, afew underage golden retrievers I'm stalking on dogster.com - the usual stuff. I decide I want to add them to iPhoto. So, I drag select the bunch of them and drag them to the iPhoto icon in the dock. Cocoa iPhoto isn't open, and so the icon starts bouncing as /usr/bin/ld
attempts to map seven thousand megabytes of unused frameworks into the iPhoto address space. Since it's a new CoreDuo machine, it takes at most, 5 minutes for this sleek application to load thumbnails for my entire photo collection into RAM, forcing this beefy unix box to swap/thrash like crazy.
As the iPhoto application continues to load, I decide my desktop is messy. Foremost amongst the mess is the bewildering assortment of JPEG visual candy. Since the iPhoto dock icon is still pogo-sticking up and down (it's like the girls on myspace with 100,000 friends - she's the star here), I've got plenty of time to freshen up my desktop. I drag select all my desktop photos/clutter and drop them into a brand new folder called 'Desktop Clutter'.
No sooner have I accomplished this when, lo and behold, iPhoto is now open and running on my machine. I click on the iPhoto icon to see how my Desktop photo import is going, and take in some more beachball/spinning progress activity before receiving this message. "Unreadable Files: 2 - The following files could not be imported (they may be an unrecognized file type or the files may not contain valid data". There's your highly advanced 1989 Cocoa for you.
In MacOS 9, with the "archaic" Finder and a run-o-the-mill Carbon application, there would be absolutely no problem with my desktop cleaning activity. In fact, if iPhoto was an OS9 Carbon application (god forbid) I could have pre-emptively thrown my JPEGs into the trash, anticipating their safe voyage into the iPhoto library. Trash, wherever. The filesystem knows where there are, and the FSRefs continue to point to them. Because my Carbon 'apple event' serves me a list of dragged files as an opaque array of FSRef objects. Unlike a path, I have no idea what the contents of these data structures are. Computer science and
software engineering 101. I'm on a need to know basis, and frankly, I don't need to know.
In fact, while the file is open, I can move it around, rename it etc. and my software never needs to know. If I truly want to know where in the file system hierarchy a file system object is, I simply query for its UTF-8 path using an opaque API. Or I can traverse the chain of nested FSRefs back up to the root of the file system. At some point in the future, after Earth has joined the galactic federation and we here on Terra have upgraded to UTF-1024 (there's a lot of languages and unique glyphs in the milky way), my Carbon application will continue to work with them because the opaque C89 API keeps me from making assumptions about the nature of the file system objects, how they are represented. The FSRef opaque data type, mysteriously, contains just 80 bytes of data. Yet it can unambiguously keep track of any object in the file system, even something with 1024 byte Unicode pathname.
Some of the functionality I describe is available to all Mac OS X applications. For instance, Preview.app is able to determine where a PDF is located, even if you move it about while it's open.
I'm not exactly sure when FSRef's entered the lexicon of Carbon programming. I do know they were introduced to accomodate Unicode path names, probably during the System 9 era. The most compelling aspect of FSRef's are that they allow you, the developer, to write software that works the way a "user" expects it to work. User's don't care about pathnames. They don't care about FSRefs. They've been shown a promise of a direct-manipulation desktop and they get really confused when it doesn't work that way.
I understand URLs. I understand Win32 UNC pathnames. I understand DOSFILE.NMS. But in all my experience writing software, the only OS API to provide the right kind of function calls (procedural or otherwise) for working with files on disk is the Carbon FSRef API set. FSSpec's didn't do it for me. Unix path's are fine, in a char way. FSRef's I found weird and disconcerting at first, but over time, I came to appreciate them greatly.
I can't possibly expect a Cocoa developer to bend their minds toward the idea that Carbon, the so-called 'out-of-date' API is, in reality, quite possibly as much as 10 years more advanced than anything else around. One can only realize the truth: There is no spoon