Shell
There’s some discussion on Erik Barzeski’s blog about shell aliases and tricks.
Lee Bennett pointed me to this hi-larious article. I love the Firefly reference, but although the sentiment is correct the quotation is not. The example scene did not actually involve the captain; rather it was about who would be in charge in his absence. Better examples would have been shooting Dobson in Serenity, the engine scene in The Train Job, and the airlock scene in Ariel.
CFBinaryHeap implements a container that stores values sorted using a binary search algorithm.
Really?
This work presents several new approaches to the construction of extensible languages, and is the first system to combine local, dynamically extensible context-free syntax with the expressive power of meta-level procedures. The unifying theme of our system is that meaning should be computed relative to local context.
I don’t think I’ve played Zelda since the 80s, but this list from Matt Gemmell is still amusing.
Still, it ought to be fairly obvious that register machines aren’t the vile and horrible things people make them out to be.
Edward Tufte (via Phil Greenspun):
Alas, slideware often reduces the analytical quality of presentations. In particular, the popular PowerPoint templates (ready-made designs) usually weaken verbal and spatial reasoning, and almost always corrupt statistical analysis.
With network capabilities required by so many applications, Cocoa developers often wonder why Apple doesn’t provide a complete Objective-C solution for network programming. While it’s possible, and often practical, to the C sockets interface in Objective-C code, it doesn’t provide the ease of use Cocoa developers expect. Fortunately, there are many third-party open-source solutions available.
The details do matter, at least on the Mac OS, the entire success of which is based on getting small details right. Pervasive click-through leads to usability paper cuts. That it’s possible never to get such a paper cut—by taking care always to click carefully in background windows—does not mean this isn’t a usability problem.
Michael McCracken has released some code for a “ubiquitous text watcher that integrates with the Cocoa text system and does interesting things with what it sees.” He also notes that the new version of OmniAppKit includes the code for the flashy OmniGraffle 3 palettes.
Steven Frank and Buzz Andersen like this new book by Joe Zobkiw. I’m not really a fan of it, though.
The book begins by repeating the annoying assertion that “The Cocoa application environment is the native Mac OS X development environment” (page 14).
Page 17 exhorts you to “read Apple’s Human Interface Guidelines and practice them,” but on page 40 the book directs you to create a metal application that has no business being metal, and page 61 includes a hideous example of excessive group boxes.
Page 22 demonstrates scalar accessor methods by…creating an infinite loop.
Page 56 characterizes Cocoa’s reference counting system as a “big gotcha.” It doesn’t explain retaining and releasing particularly well, nor does it link to more comprehensive coverage.
Page 63 uses the application controller’s +initialize
method to set the application’s defaults if they have not already been set. It uses an integer where a boolean would be a better fit, and it creates NSNumber
objects instead of just using -setInteger:forKey:
. More seriously, the example probably should have used -registerDefaults:
instead of actually setting the defaults.
Page 73 says “pop-up menu” when it means “contextual menu.”
In a great example of the book’s cursory coverage, page 126 recommends embedding frameworks in your application’s bundle without mentioning that the key to doing this is to use the magic @executable_path/../Frameworks string for the installation path. It merely tells you to use Project Builder’s stationery, which is pre-configured for the framework being in the Library folder.
Pages 143 and 158–160 use CFPreferences
(and other Core Foundation stuff) rather than NSUserDefaults
(and other Cocoa stuff) in a Cocoa example without explaining why.
Page 155 says to give your .prefPane package a custom icon by copying from the .icns file’s Get Info window and pasting into the Get Info window of the .prefPane. First, this won’t work. You want to copy the contents of the .icns file, not its icon. Second, you’d have to re-do this process after each clean build. It would be better to use Project Builder to set the icon using the Info.plist file. Now, maybe there’s some reason this doesn’t work with .prefPanes, but if this is the case the book should say so.
Page 163 says that status items “are intended to display hardware or network status/settings only. This is why you will see iChat and Airport[sic] but not Mail.app.” Now there’s a clear distinction.
Page 169 creates a menu using [[[NSMenu alloc] init] retain]
and only releases it once, thus leaking it.
The Threads chapter is basically an introduction to what threads are. It doesn’t really talk about Cocoa thread-safety, and in fact the examples are thread-unsafe. Nor does it mention how to communicate between different threads.
The Terminal (NSTask
) chapter doesn’t really add anything beyond Apple’s documentation and sample code. It doesn’t discuss buffering issues, which are probably the biggest gotcha here. It’s also not a good example to emulate: it uses polling, it doesn’t protect a shared variable with locks, and it calls the AppKit from a child thread. For some unknown reason, all of the threads end with calls to [NSThread exit]
, even though the book ascribes no benefit to this practice.
The XML-RPC chapter has some information that’s not in other Mac books to my knowledge. However, it contains this confusing bit of code:
// Add the users choices to the dictionary to be passed as parameters params = [NSMutableDictionary dictionaryWithCapacity:2]; [params setObject:selectedProduct forKey:selectedProduct]; [params setObject:selectedColor forKey:selectedColor]; // Create the array to specify the order of the parameter values paramsOrder = [NSArray arrayWithObjects:selectedProduct, selectedColor, nil];
I would have made the keys and array elements string constants like @"ProductColor"
and @"ProductProduct"
. Not only does that make the intent clearer, but it won’t fail if a color and a product have the same name.
And the next page goes on to release params
and paramsOrder
both of which were already autoreleased. The subsequent SOAP chapter does use readable string keys, but it has the same over-releasing bug.
Page 298 promises to help find “Application Support Directories,” but apparently the “Application Support” folder isn’t one of them. It would have been better to provide some alias-savvy code for locating and creating the application’s folder in ~/Library/Application Support.
Page 300 uses NSOKButton
instead of NSAlertDefaultReturn
. Luckily, the constants have the same value so the code does work.
Page 301 again over-retains an NSMenu
.
Although there are a lot of errors (and more typos) in this book, I sympathize. It’s tough to get all the details right, and many technical books do no better. However, my larger concerns are the choice of topics and the depth of coverage.
Don’t let the title fool you. This is not an advanced book, nor is it about techniques. Instead, it’s a guided tour through some example projects that are off the beaten path. Many of them are covered in other books and articles, but some are not. Thus, it’s great that this book exists, but it will not be of interest to everyone. The advanced book I was hoping to find, would cover things like AppleScript, inter-thread communication and threaded application architectures, application code structure, databases and persistence, AppKit gotchas, third-party libraries and wrappers, medium- and lower-level networking, Quartz tricks, and optimization.
The book’s coverage is wide and shallow. It’s based around a series of examples, and it’s wont to show a simple code example and then paraphrase the code in prose. As a result, in many cases I felt it didn’t add much value over Apple’s documentation and sample code. I would have liked to see less focus on what and more on why. Also, if a book is based around examples, I would expect them to exhibit best practice techniques. In contrast, Bill Cheeseman’s Cocoa Recipes manages to use an example-driven style without ignoring the rationales, subtleties, and gotchas.
Cocoa Programming by Anguish, Buck, and Yacktman is both wider and deeper than this book. Not only does it have great introductory material (for those who know how to program but don’t know Cocoa), but it also contains a lot more advanced information. Every Cocoa programmer should own this book. Its only significant flaw is ignoring AppleScript—as do all the other Cocoa books I’ve seen.
Mac OS X Advanced Development Techniques does contain chapters on Carbon and Cocoa plug-ins and on XML-RPC and SOAP. I don’t know of other books that cover these, but Apple (see preceding links) and O’Reilly have already done a decent job.
I hope someone will step in and write a truly advanced book about Mac OS X programming. Until then, I recommend Apple and Omni’s mailing lists, Mulle kybernetiK, O’Reilly, Stepwise, and developer blogs.
Buzz Andersen has done some more reverse engineering of Apple’s DRM. He found the QuickTime atom where the DRM information is stored, but wasn’t able to play the file after removing it. Code is included.
SQLite now supports in-memory databases, attaching other databases as tables in the current database, and compacting.
An adventure is a sign of incompetence; everything you add to an explorer’s heroism you have to subtract from his competence.
—Vilhjalmur Stefanson