Macintosh

There are 53 entries in this Category.

Dealing with it with Natural Language entry

John Gruber just posted a little piece titled Deal With It. He points out something that annoyed me since System 6′s Alarm Clock widget (or was it Calendar?):

Controls like the system standard date and time controls walk the fine line of compromise: They always enforce a valid date and are composed of separate fields that you tab through individually, but when you type the date or time separator, they move to the next field. So, if you go into Date & Time in System Preferences and click the time there and enter 12:34, it will automatically put the minutes into the next field, even though your first click selected the hours.

Stupidly, iCal really implements the components as separate fields and requires you to type the tab key whenever you want to enter the next date component. Type the date separator and it just beeps at you. IMHO that’s the main point that makes it annoying.

However, even if a custom control for entering formatted values may require as many or as few keystrokes as a free-form text field, the field will feel more natural. As long as it is clear what you are expected to enter into the field, and how to enter it. This can be done with the little grey “placeholder” text some fields on Mac OS X have these days, but is very hard to get right.

For instance, it’s not quite easy to parse any kind of date a user may type into a date & time field. Some of the ambiguity can be resolved using the system’s locale-specific date & time settings (quick: 10/09/2007 — 10th of September or 9th of October?), but coding everything, including “in 3 days”, “3 days from now”, “next wednesday” and all variations that may exist in a particular language, can be a lot of work and require a good deal of processing. And once you start accepting simple things like “Today” and “Tomorrow”, where do you stop? What about “Next Easter” or “The Next Monday that is the 1st of a month”…

And suddenly we’re in the area of the Uncanny Valley and the Turing Test: How much can I expect a free-form field to understand? Many people will not even try such complex expressions because no other program understands those. If Apple implemented a consistent free-form date field, users would slowly learn that every application has a field that works, would learn in one that they can do more complex stuff with it, and then would try that in other apps as well. That’s how MacOS has always used consistency to the user’s benefit.

But still, they’d have to learn the limited language the computer understands. It would just be another command-line. And making a restricted language too close to English has often been the downfall of English-like programming languages: The closer a language is to natural language, the more we tend to only memorize the general meaning. Then, when it comes time to use that command again, we reconstruct the sentence, get one word wrong and have no idea why the stupid computer doesn’t understand. We dive nose-first into the uncanny valley.

However, John’s posting makes me think that not the graphical user interface, but actually the command line will be the future of user input. Right now, our level of interaction is that of the typical European in rural China: Point at two things, and hope the other understands. Once dictation matures, this can change to a degree. We can enter commands by voice, like speech recognition already allows to a degree, but we’d also have to be able to dictate new data, names, addresses, whatever, to make this feasible.

This would not replace the GUI with that speech-controlled command-line, but augment it. Right now, we’re at the verge: NSDateFormatter already understands a lot. But you still have to know (or test) its limits to use it. But luckily, our users are getting more proficient. Somewhere in the middle, our coding skills and users will meet, and voice-control will be an everyday occurrence. Until then, we’ll have to cope with The Stupid Computer(tm) and its stubborn misunderstandings…

But yes, the future is the command-line, not the WIMP-interface.

Update: I’ve had the time to read the complete Three Hypotheses of Human Interface Design-article that John Gruber referenced in excerpts. Maybe I’m not getting it, or maybe it’s the equations that are actually important, but I think in general most of the things written there can be found in other HCI books:

Measuring the number of actions and weighting them is a very common task in usability research. For example, Jef Raskin’s book The Humane Interface provides some examples of this in one of the early chapters, so the readers at least have the basics down before he starts with his actual theses.

Similarly, cognitive load, and how much more important it is than many people think is covered in Steve Krug’s Don’t Make Me Think, where he also points out how people are always spending about 80% of brain power on what they actually want to achieve, and only 20% on actually using your application.

So, no, I don’t think the author actually invented it (well, it may be a double-creation, but like everything, it’s been there before), but his article is a good starting point into the subject matter, IMHO.

Debugging memory on OS X

Just a short note so I don’t have to Google around Apple’s web site for hours: There’s a few useful environment variables that can be set to help in debugging disposed memory accesses etc. Most of them are documented on Enabling the mallocDebug features and Finding memory leaks:

  • Set DYLD_INSERT_LIBRARIES to /usr/lib/libMallocDebug.A.dylib. This makes you link against libMallocDebug, which prints errors on bad accesses. Set a breakpoint on MDprintf to see a backtrace when this triggers.
  • set MallocScribble and MallocPreScribble to YES to initialize new memory to 0xAA and freed memory to 0×55, which will also help finding out when you’re accessing bad memory.
  • set MallocGuardEdges to YES to make it harder to smash memory and instead get a bad access exception.

Any other memory debug tricks you guys have?

Intel/PPC oddity

Something odd I noticed today:

#include <CoreServices/CoreServices.h>

int main( int argc, char** argv )
{
    UInt32 a = 0;
    a += (double) -1;
    printf( "%d\n", a );

    return a;
}

this code prints 0 on an Intel Mac, but prints -1 on a PowerPC. So, essentially the PPC seems to just overflow, but the Intel CPU seems to refuse to go below 0.

I guess it’s a matter of definition, but does anyone know the official reasoning behind this? I.e. know whether the C standard or Intel/IBM/Motorola specify that this should be so?

Just curious…

Software ideas up for grabs

In case there are any programmers out there who have lots of time on their hands and don’t know what to program, here’s a few ideas that I’m surprised nobody has implemented, along with my suggestions on how you could fairly easily implement them.

Web Site Layouter

CSS supports absolute positioning of elements. However, most tools available for WYSIWYG site design restrict how you can position stuff. iWeb comes pretty close, but just doesn’t give you enough flexibility for themes, and Sandvox and RapidWeaver both only flow text and objects and don’t let you just position stuff by dragging.

So, my idea is pretty simple: Create a tool that takes HTML and renders it on the screen. Design this as “layers”, each of which has its own entry with absolute positions and the left/top values defaulting to 0. Use a WebView to correctly render each layer at 0,0 and draw it into an offscreen buffer (i.e. NSImage). Then draw all of these layers into your document window. When the user clicks, you loop over your layers in the reverse order as you’re drawing them, and check the pixel at the click position whether it’s opaque or transparent. If it’s opaque, that layer was just clicked.

Now, when the user clicks a layer, let them drag the layer, live. Save the position, and draw the buffered layer at that offset position. When the user requests to upload the page to a server, write that position to the CSS file.

WYSIWYG item positioning and correct HTML rendering the easy way.

Now, the hard part will be to actually edit each layer. You could do plugin-like objects that just output HTML to render that layer. E.g. a “table” plugin and a “styled text” plugin, and you could even use the new cool NSTextView features in Tiger to let users pretty nicely WYSIWYG-preview their images embedded in text. But really, positioning is key. If you’re a proficient CSS-maven, you might even manage to add other cool features, like Interface Builder’s “resize springs” etc., though that wouldn’t be as easy as what I outlined above.

Another neat feature would be a “block hierarchy”. What I mean by that is that users and plug-ins can define block types, a block simply being a chunk of HTML. Many of these blocks will do their thing to other blocks. E.g. the page would be a block that has one area for the navigation block, and another for the content block, and draws the design around those.

One block could be a “box block” that simply renders a box in the current theme and then puts another block with the actual contents inside it. Another block could be a table of image thumbnails in a folder, another a list of files in a folder, yet another block could be a box with a link to an RSS feed, that automatically adds the correct meta tags to get the blue ‘RSS’ button in Safari’s URL bar.

The neat part here would be that blocks generate their HTML based on the current theme. So I can have lots of boxes in my text for common elements like callouts, images with subtitles etc., and when I change the theme, they all change to match.

And as I mention above, there could be native-code plugins that are also blocks, doing all kinds of magic.

Simple Database

Basically, the code for this has already been written. You just link to libSQLite, stuff the database file and a layout description file into a document package and slap a GUI on top. If you look at AppleWorks’ database module, that’s the kinda structure I’m aiming for. You create fields, you can put them on one or more layouts, you can edit, view and print a layout, and search through the fields in the database and show the results using a layout of your choice.

Slapping a GUI on top would essentially mean you code a WYSIWYG UI editor that lets users place text fields, check-boxes, radio buttons, pop-up menus, list boxes, fields with stepper controls (“little arrows”) and any other UI element you can think of on the screen. Each of these would be hooked up to one particular database field in a table. Keep in mind that users may want different views on the same fields, though.

So while they want to be able to just compose a window full of controls, they may want to print as a table/list one day, and as a stick-on label the other day. So, you’ll want to have some simpler and fancier styles as well as standard controls, and you’ll want a table view and list view (i.e. several records shown on the screen, with their controls, not just one).

Also, the database may contain more information than you’d want to print on a label for shipping, so allow for not having all fields in a layout. You’ll also want to offer some drawing tools in case someone wants to draw separator lines, boxes, or put a logo on his disk labels, and don’t forget a text tool for e.g. labelling (groups of) fields with text that doesn’t come from the database. Of course, we also want to store text and styled text in the database.

You’ll probably want to have one object that owns all the controls for a particular field in a particular layout. That way, a user can change the display style of a field. E.g. you could have a number field which can be shown as a slider, an edit field (with or without stepper control), or as a radio button group, or as a list field, or… So, you’ll want to be able to show the same field with a new style just by changing a property, but without losing the actual data.

Main purpose of this: Just general keeping and searching data on-disk (user accounts, info on books I lent out, database of addresses to send my newspaper to…), but also printing of lists and labels.

And once you have that finished, there’s always advanced features: File references (i.e. store an AliasRecord as a BLOb) would be kinda nice, as well as references to records in other databases. If you give each entry a unique ID, you could probably just store this unique ID, and store the database file for that ID along with the field definitions and layouts “globally” in your document (i.e., I don’t think you’d need to be able to have a different database for each record).

In addition, you could add a little expression parser that lets you create field values calculated from other fields’ values (e.g. calculate someone’s age based on their birth year, or concatenate a “product prefix” and “product version” field to generate a product code, or whatever…).

You can also go wild with regard to search, import/export, trigger AppleScripts when a particular field is changed, put a plainly readable XML version of a database into your package to make it easier to spotlight and to allow third-party apps to read your databases without having to restrict yourself when changing the database format… there’s a lot of cool features in there, but the basics are pretty trivial to implement and only require some time and polish.

Audiobook/Theatre Lines/Podcast Recorder

This last one is probably niche, so I’m not too surprised it hasn’t been done in this form. Still, I think it crosses enough markets that it would be possible to make a viable product out of this:

Basically, it would be an audio-recording app. Feature set not unlike Audacity (or an updated version of Farallon’s SoundEdit), but with one distinction: A workflow that allows me to set chapter markers by pushing a button during recording, and perform other simple but common editing tasks while the recording is still going. What for? Well, several uses:

  • In Podcasts, add chapter markers or put bookmarks in spots where e.g. the Skype recording has broken up.
  • In audiobooks, mark the start of a new sentence. If I mis-pronounce, I simply click a button, and everything up to the last chapter marker is marked for deletion. I simply read the sentence again (and again, and again) until I get it right.

So, the editing that happens would only consist of marking up the recording with metadata, and updating the display (which would probably be some sort of wave-form display with selection). There would be no need for the delays often caused by stopping and restarting the recording, as it would just keep going. Only once the recording has finished would the actual sentences be deleted. Heck, it wouldn’t even have to delete them right away, it could keep the various versions of the same chapter and let me choose between alternatives.

While Garage Band has a vaguely similar feature, it is aimed at musicians: You can mark an area that is a certain time long, start recording, and start playing your instrument. Once recording hits the end of the time range, it will then restart recording from the beginning and let you play a new version of this particular range. But it is always of fixed length. When I’m reading a novel as an audiobook, there is no predefined length for a sentence. I might try reading it fast, realize that doesn’t work, then want to re-read it more slowly.

So, why do I mention theatre lines here? Well, when I learn my lines for a play, what I usually do is I record everything into an MP3 and then listen to that on the morning commute. By hearing my lines every day, having them repeated to me over and over again, I can much more quickly memorize everything, and I can learn the lines on occasions where I can’t have the textbook in front of me. The general workflow is the same as an audiobook, though: Read text out loud, and delete any sentence I screwed up and record it again until it’s OK.

Any takers?

If anyone happens to implement one of these ideas or knows of applications that already do this, let me know. (And no, FileMaker or MySQL with phpMyAdmin don’t count – I want something small and simple, like Tables, but for databases/web sites).

Update: Added mention of blocks to web app.

Debugging Assembler on Mac OS X

The thing a programmer probably does most is, unsurprisingly, debugging. Not that programmers necessarily love debugging, but if you don’t have a high pain tolerance for debugging, you probably don’t want to pursue a career in programming. On the other hand, if you like the challenge of the bug hunt, you should try getting into this biz. Or into exterminating. Whatever makes you happy, man.

Anyway, my recent posting on Intel Assembly Language Programming on Mac OS X kinda left you hanging in the air on this one. I didn’t say anything about debugging. Why? Because, honestly, I hadn’t got that far yet. Of course, the first bug didn’t leave me waiting for long, so here’s some handy tools if you want to debug your assembler program.

First, you need to compile your assembler source files with GCC using the -g option. That will give you debug symbols, which means the debugger will show you each line. Once you’ve done that, you just launch GDB, on the command line, as usual:

% gdb path/to/your/executable

You’ll get the GDB prompt you may have already seen in Xcode’s debugger console. Type in

(gdb) start

and it will jump to the start of your main function. GDB will always print the next line, and you can use the step command to execute it and see the next one. Of course, you may want to see what is in a particular register or at a particular memory address. Easy:

(gdb) print/x $eax

will print register eax as hexadecimal (that’s what the ‘/x’ means – there’s also ‘/d’ for decimal, ‘/c’ for character, ‘/s’ for string and ‘/t’ for binary). If you want to view a memory location, you use the ‘x’ command instead.

(gdb) x/1xb $eax

will take the address in $eax, and print 1 byte at that address in hexadecimal. The parts after the slash decode into /<count><displayFormat><type>. displayFormat is the same as the thing after the slash when you print, count is a number indicating how many to print, and type is ‘b’ for byte, ‘h’ for halfword (2 bytes) or ‘w’ for word (4 bytes).

Oh yeah and to get out of gdb again, the command is quit. Happy debugging!

Update: I recently realized I’d omitted two important little tricks from this description: If you don’t have debug symbols, you can still step through code. The relevant commands are

(gdb) si

which steps through code by one instruction (this even works with system functions etc.) and

(gdb) p/i

which disassembles and prints the current instruction.

Nice Intel assembler text…

[two of Intel's instruction set manuals]

I’ve recently been looking into assembler coding a little. I learned assembler theory back in High School in Mr. Trapp’s computer programming elective, and later learned a bit of 68000 assembler as well, but never got round to actually getting into it when the PPC arrived on the scene. So, when I recently heard at work how one can get a whole bunch of Intel reference books for free, I thought this might be a good opportunity to learn x86 assembler. After all, I’m a parser and compiler geek, it’s kind of a gap in my skill set if I can’t do the backend.

Now, trouble is, while there are many tutorials for Linux and Windows, I couldn’t find a single one for Mac OS X. So, I started googling, assembling C code and bothering some developers I know and others on mailing lists with my questions, and I thought I’d share my first findings:

  • I got a link to Apple’s Mac OS X ABI docs. This is really good, as it documents an important part on OS X in detail: How to align the stack (on 16 bytes, no matter what Intel’s docs tell you), and how to call your own functions.
  • Aforementioned 16-byte stack alignment is not always necessary, but when you call a function, you must give it a properly aligned stack. When you are called, however, the stack will have the return address on it, which is 4 bytes. So, after you push the base pointer on the stack (4 more bytes), you have to move the stack pointer by another 8 bytes at least to make it aligned on a 16-byte boundary again.
  • A nice way to learn assembler is by writing very simple C programs and using gcc -S my_simple_c_program.c to get it translated into assembler code. Note that by simple, I recommend you start out with stuff that doesn’t use any system functions, because those are dynamically linked and make for rather complex assembler.
  • To compile such a program, simply pass it to GCC again, as you would with a C source file. E.g. gcc my_simple_c_program.s -o my_simple_c_program

This might be a good point to mention my Memory Management chapter in the Masters of the Void C tutorial again, which illustrates how memory works. As I learn more, I may post supplements to that that slowly teach you assembler. Well, I’m not promising anything, but I’d love to do that.

Red Sweater Blog: Build your own damn HIG

Daniel Jalkut recently blogged about building your own damn HIG, where he takes inspiration from John Gruber’s C4 speech on why the Human Interface Guidelines may be dead. If you haven’t read it yet, you may want to so so now.

One thing he overlooks is that, just maybe, computers have become more sophisticated: Back when the Macintosh came out, resource limits forced elements on screen to be simple. Now that we have more colors and more pixels, and bigger hard disks, there’s room for more variation, without making things too difficult to recognize.

Similarly, back then Apple pretty much had to introduce people to the GUI. “educate” the users. Nobody knew insertion marks, pointers, the mouse, menus… These days most people are familiar with the basics. Just like a caveman would probably not have understood what a button was before the invention, the race as a whole had to learn, so to say. What would be an odd, stuck pebble, maybe, that you can push a button and cause something else to happen, maybe miles away, is a more recent invention.

That you can move a mouse and a pointer will move synchronously on the screen, and that the “world” on the screen basically works the same as the real world, is even more recent. But these days, children see their parents use a computer, and much of a computer’s chips and usability has partially made it into simpler devices, be it the iPod or your TV or your cable box.

I also think that he’s overlooking a third option, apart from ignoring the HIG or just following your stomach: Doing your own usability research and creating your own UI, inspired by the basic conventions of the platform you’re on (not applicable items are shown dimmed, close boxes have an “X” symbol and either a certain shape or color…).

I often recommend the book GUI Bloopers by Jeff Johnson to people who don’t know about usability. Why? Because even though it mainly has screen shots from Windows 95 and System 7, it is still perfectly applicable to today’s user interfaces. With the vocabulary of these simpler operating system user interfaces, with these prototypical, I might even say archetypical graphics as examples, it shows you the thought behind the guidelines, not the word up front.

It’s like the Bible: “An eye for an eye” doesn’t mean: If someone hits you, hit back. Rather, it tells you to consider commensurability: If someone pokes out your eye, don’t kill his family as it happened in those days. So, what seems to be a very violent command to today’s audience, was actually an obvious call for moderation in the context of ages past.

And before I go off on a tangent, I’d better close this posting.

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.

Carbon for the Cocoa Guy: Handles

One of the more confusing aspects of MacOS programming is the Handle. That doesn’t have to be so. I’ll quickly illustrate the history of the Handle and then everything should become clearer. I’ll also include a little memory-management-101 at the beginning.

Memory Fragmentation

When you use malloc() or similar APIs to allocate memory, you face the problem of fragmentation: Imagine you have the following (top) situation in memory:

[Illustration of three consecutive memory blocks, where the one in the middle gets deleted, fragmenting memory]

 

You have three blocks of memory: The blue one, the green one and the red one, each 6 bytes in length. Now, you dispose of the green one by calling free() (bottom). Now there’s a six-byte hole between the two blocks. The total free memory (white blocks) is 108 bytes. Trouble is, since the computer can only allocate contiguous blocks of memory, the largest block you can allocate is 102 bytes.

 

Now, we can’t just move the red block to the left to make more continuous free space available, because our program keeps track of each block by its position (its “address”), and moving it would change that address. The system would have to go through your program and change each occurrence of the moved block’s address, which is simply impossible since only your program knows which parts of its memory are used for what. Not to mention it would cause pauses in execution. So, if you needed 103 bytes, you couldn’t get them, even though we have 108 free bytes in total, more than we’d need.

[Illustration of three pointers pointing to the same memory block]

 

Handles – a modern solution to fragmentation

So, what Apple did is they created the Handle. A Handle is essentially a centralized way of storing pointers to memory blocks, so the system only has to change one centralized pointer when it needs to move a block to make more memory available.

[Illustration of three Handles pointing at a master pointer, which in turn points at the memory block]

 

Each pointer to the actual memory is owned by the system, and kept in a central table of pointers (the “master pointer block”). When you want to allocate memory, you ask the system to do it for you using the NewHandle() function. The system gives you a Handle, which is a pointer to the actual master pointer it owns. You only use this Handle to remember where your memory is. When you want to access the memory, you de-reference the Handle once to get at the pointer, and then use that pointer like any other.

The advantage of this is that all access to memory goes through those central master pointers. When the OS has to move a block of memory, all it has to do is change the master pointer, because all Handles point there. The OS also takes care to bunch up all master pointers at the start of memory, and to re-use old master pointers, so that they can’t fragment memory.

Since we don’t want the OS to move around our master pointer while we are using it, there is an HLock() function that lets you mark a Handle as immovable, and HUnlock() to make it movable again as soon as you are finished. To get rid of a Handle, there is the DisposeHandle() function (So, NewHandle/DisposeHandle can be seen as roughly equivalent to malloc() and free(), though they’re not exchangeable).

History, or Carbon, intervenes

By the time Apple switched to Mac OS X, pretty much everything was a Handle. There were ControlHandles used for buttons, MenuHandles used for menus … Since Mac OS X was very different under the hood, Apple needed to change the way menus and controls worked. Mac OS 9 had a single address space, so it was easy to just hand a menu Handle between applications.

But Mac OS X has protected memory. For security reasons, every application runs in its own segregated area of memory, with very limited access to memory in other applications. Moreover, the Window Server, responsible for drawing windows and the menu bar, is now a separate application. You can’t just pass it a MenuHandle, it has to be something different.

Since Apple didn’t want to break everyone’s code, they changed the name of ControlHandle to ControlRef, but kept the old name for compatibility, even though it isn’t a Handle anymore. Which means you have to be extra careful with xxxHandle data types.

Handles – a solution still used today

Unix offers a slightly improved version of the same approach: Each address a program uses isn’t a real address on the RAM chip, but rather a “virtual” address that gets translated to a physical address in RAM. There is a translation table for translating addresses from virtual to physical. When the OS needs to move a block of memory on the chip, it essentially just changes this translation table (I’m simplifying here). So, your code doesn’t even have to know its memory just moved, doesn’t have to mess with Handles. But that needs a faster, better CPU with a Memory Management Unit, which early Macs with their 680×0 CPUs didn’t have (at least not until the Performas and Quadras).

Since Mac OS X is a descendant of BSD Unix, it inherited this, and Apple uses this new Unix-style mechanism in most new APIs. Also, in Mac OS X, a Handle is never moved. Since, under the hood, the master pointer’s memory block is allocated using malloc(), it’s not necessary anymore. So, if you write new code, use malloc()/free(). If you need to talk with APIs that still use Handles, use NewHandle()/DisposeHandle() and double-de-reference, but there’s no need to call HLock()/HUnlock() anymore. Though it doesn’t hurt either.

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.