launchd tech talk
In case folks might have missed it : Launchd: One Program to Rule Them All Tech Talk @ Google, with Dave Zarzycki, the launchd dude.
In case folks might have missed it : Launchd: One Program to Rule Them All Tech Talk @ Google, with Dave Zarzycki, the launchd dude.
Hello Everyone,
Two friends of mine who are excellent musicians (Trumpet and Trombone) are moving to Philly this summer, and they’re looking for good community music groups (band and/or orchestra). They don’t know anyone in Philly. *I* don’t know anyone in Philly would know what groups are good in the region. If anyone has suggestions, leave a comment or drop me a line at markd@borkware.com. Thanks!

Hello everyone,
The next Pittsburgh CocoaHeads will be April 24, 7:30 pm at Newell Simon Hall, room 3000. Unless someone wants to talk about something else, I’ll babble incoherently about Unit Testing and Code Coverage, plus a peek at the Google Mac Playground and CoverStory.
We’ve got a google group / mailing list at http://groups.google.com/group/cocoaheads-pittsburgh. Please join if you’re in the area.
The Time Capsule I ordered a while ago has arrived. Woot! Remote Backup Nirvana is coming my way!
So far, it’s been working out “eh”. It took a couple of tries to get it onto my WDS network, and I’ve gone through a number of scram-the-backups-and-redo-from-scratch getting things set up. Here are a couple of first impressions.
stated on every backup. I’d need to backup a few megs, which would take two minutes, and then it would sit at “Backed up 10Megs of 10Megs” for 5-10 minutes, all of which was looking at mail messages. It turns out I had a lot (over 65,000) of “deleted” messages that weren’t in the trash, weren’t in any mailbox, but showed up if you command-L while viewing the inbox. Control-clicking on the mailbox and choosing “Erase deleted messages” did nothing. I had to select each Inbox (I have 3) and choose “Erase Deleted Messages in Selected Mailbox” from the menu (or use command-K) Once I did this, a backup (including an email check) is about two minutes from “Backup now” til it completes.

And mdutil -i off /Volumes/blah doesn’t turn it off either. Even a reboot didn’t help. Sigh.
Hopefully once some of these annoyances are worked out I think Time Capsule will work out a lot better in backing up my, and the wife’s, MacBooks. Before this we had an “rsync to a DL-DVD-sized dmg on a Mac mini” setup, and hoped it didn’t fill up the disk image, plus waiting for a DL disk to burn, and hope it didn’t fail part-way through with media errors.
Just in case you’re reading Learn Objective-C on the Macintosh, and you’re wanting to make a “Foundation Command-Line Utility” project in the might (or might not) be new Xcode which might (or might not) be associated with the latest iPhone excitement, you’ll probably want to look under “Command Line Utility” on the sidebar, and choose “Foundation Tool” from the project picker. They may (or may not) have moved it from previous Xcode versions. Or not. You didn’t hear it from me,
I usually don’t like to Pimp my own Warez, but Sir Daniel Punkass pointed out to me that Learn Objective-C on the Macintosh is quite applicable to iPhone development, especially for folks who don’t already know Objective-C. Sometimes I’m a bit clueless.
LoC is an introductory book, but assumes you know C (it’s officially the follow-on to Learn C On the Macintosh). It covers a lot of the basic stuff you need in Cloud-Cocoa Land - especially memory management, which we go over a lot in the latter half of the book, since memory management is the place that many Cocoa programmers have problems.
We tried to make it as non-boring as possible, so I think even experienced programmers can get something out of it. From a twitter in response to Mr. Punkass, Diego wrote “started on the book and it’s very good. straight to the point and doesn’t linger on topics. which i like. thanks for the tip” (Thanks Diego!)
On the down-side, it doesn’t cover the properties syntax, or the new fast enumeration syntax, but once you have the basics of the language under your belt, you should be able to pick those up quickly.
Want to learn more about OpenGL ES? http://www.khronos.org/opengles/ has some information. The OpenGL ES 1.1 specs would probably be of the most interest.
At the last CocoaHeads/Pittsburgh meeting, we chatted about setting up a mailing list, and maybe using a Google Group. I’ve gone ahead and set one up:
http://groups.google.com/group/cocoaheads-pittsburgh.
Wheeeee!
Apple’s released some new/updated documents. The Threading Programming Guide looks particularly interesting, especially if my LNC episode inspired you to not run away screaming.

Wonder if a signed integer value and a sanity check for <= 0 would have caught this case? (Mail.app on Leopard. BTW. Anyone know how to get Mail.app on Leopard to delete messages without moving them to the trash? command-delete moves to the trash, and doing a “Cut” takes a freakishly long amount of time.) Radar 5353034.
For folks in the Western PA area, the next CocoaHeads/Pittsburgh will be thursday, February 7. I’ll be talking about NSOperation.
I had the pleasure of recording another Late Night Cocoa podcast over at the Mac Developer Network. This time I blabbled about concurrent programming, including some chatting about NSOperation.
If you know something about Cocoa programming, I’d like to encourage you to do a LNC podcast. Scotty is a pleasure to work with.
I’ve been using Pages for writing new AMOSXP chapters, and for the most part, it’s a pleasant experience. I’ve just about got the NSOperation chapter put to bed, and was making a PDF to send off to the first round of reviewers, when I noticed the generated PDF output was beyond horrible. Here’s what it looked like on-screen:

and here’s what the resulting PDF looked like:

Hideous, isn’t it?
Turns out that Pages is honoring the “Turn off text smoothing for font sizes x and smaller” when generating the PDF, and using bitmaps for the smaller font sizes. I have that set to “12 and smaller” because anti-aliasing plus my eye correction conspire to make things difficult to read. Why Pages is using this setting for PDFs is beyond my comprehension (and I hope it’s just a bug - VoodooPad does the RightThing. Filed Radar 5698417). You’d think that PDFs are being made for someone else’s consumption, and so wouldn’t carry along personal preferences like this.
My cow-orker, Mike Morton, gave me a little bit of advice over a year ago that’s proven to be incredibly useful: “In your -dealloc, release objects in the same order they’re listed in the @interface“. This makes it really easy to double-check your work and make sure you’re releasing everything you need to. It also makes maintenance easier: skim down your -dealloc and compare to your @interface before you land your code.
It’s Macworld 2008 time. I had Google Booth Bunny duty on tuesday. When I wasn’t working the booth, I wandered around the show floor with a camera, with the obligatory web gallery.
My friend and cow-orker Greg Miller has a piece published at MacTech: Exploring Leopard With DTrace.
DTrace is cool. DTrace is awesome. Go read this.
Apple provides downloads for OS X version for developers with seed keys. That’s cool.
Apple’s webservers cut off long downloads after twelve hours. When it takes twelve hours and fourteen minutes to download something, that’s not cool. I don’t want to think how many multigigabytes I downloaded before figuring out that twelve-hour cutoff.
Jonathan Wight said on IRC one day, “dude, use Speed Download“. I did. It works. I watched the progress meter at 12 hours. download speed went to zero as expected. A couple of seconds later it cranked back up Fourteen minutes later I had a finished download. That’s cool.
One thing that made me happy, and was greeted with applause at WWDC, was the news that ZeroLink is gone in Leopard. The linker is now fast enough to make ZeroLink unnecessary.
So what was so bad about ZeroLink? The first problem wasn’t actually ZeroLink’s fault - it was Apple making ZeroLink on by default for new Xcode projects. A common refrain heard from new Mac programmers was “I made a Cool Little Cocoa App, sent it to a friend it won’t work for him. What’s wrong?” ZeroLink.
ZeroLink performed its magic by demand-loading object files, and those object files weren’t included in the application bundle until several Xcode revisions later. So sending an App to a friend (or a reviewer, or a cow-orker) would mean sending them a broken app. Then the programmer would ask for help on a mailing list or IRC, get told to turn of ZeroLink, and then rebuild and re-send. In fact, the Feenode #macdev FAQ has a special section just for ZeroLink.
This was embarrassing and demoralizing, especially for someone new to the platform. New, small projects didn’t benefit from ZeroLink anyway, and you have to have a pretty large program before the time savings is noticeable. Someone with a project that big will have someone intimate with Xcode who would know about ZeroLink, so need to have it on by default.
The second problem was that ZeroLink introduced instability, with its frequent refrain being “I’m getting weird crashes”, which are fixed after turning off zero link. I got paid for a full day’s consulting tracking down a strange C++ operator new overload. The daily smoke test built and ran great, but development versions crashed and burned in weird places. We finally tracked the main difference between the developer builds and the automated builds: ZeroLink. Turned it off, rebuilt, and life was happy ever after. This particular app (which was freaking huge) was broken down into lots of frameworks, so link time wasn’t that much longer than with ZeroLink. (Because of this framework breakdown, I was able to pull some command-line tricks to prevent unnecessary recompilation of other parts of the system, and greatly reduced my turnaround time on a TiBook500 vs the G5-weilding full-timers, but that’s a story for another day.)
Good bye ZeroLink.
Chris Hanson and Scott Stevenson are organizing NSCoder Night in the Silicon Valley, a weekly event where Cocoa geeks can hang out for coding and mayhem at a coffee shop or a pub. It sounds like it’ll be a huge amount of fun.
For folks in the Pittsburgh area, Jeff Hunter is organizing DevHouse Pittsburgh thursday the 8th. It’s similar to NSCoder and SuperHappyDevHouse, but in the pittsburgh area. Some of the local CocoaHeads will be there.

After about a year off, Pittsburgh Cocoaheads is going to be starting up again. Second thursday of the month, 7:30 - 9:30 PM, on the CMU campus (Newell-Simon Hall. Room 3000 or 3001. There will be signs pointing the way)
And for folks who don’t know about CocoaHeads, it’s an international Mac Programmer’s group. Pretty much an excuse for Mac programmers to congregate and geek out. Right now we have 20ish chapters in seven countries, two hemispheres, and four continents. Check out CocoaHeads.org for a chapter near you. If there is no local chapter, or if your local chapter hasn’t met in awhile, feel free to drop us a line and become an organizer.
CocoaHeads started in Pittsburgh several years ago when AgentM and I decided to start a Mac programmer’s group because there was nothing in the area. He came up with the name and the logo, and did a lot of evangelizing in the early days. I’m glad AgentM picked the name : I would have come up with something horrible like “Western Pennsylvania Mac Programmer’s Geeking Out And Food Eating Society”, which doesn’t quite have the groovy ring of “CocoaHeads”
With all of the love and attention that Flying Meat’s Acorn is receiving, I figured I would remind folks about VoodooPad.
VoodooPad is a personal Wiki that lets you write stuff and link things around. When it sees words in CamelCapsStyle, it automatically turns it into a link to a new page where you can write more stuff. All pretty standard wiki stuff. It uses the OS X text engine so it has all of the standard word processing features you’ve come to expect, including stuff like tables and lists. This is especially nice because I get a lot of my emacs key bindings along for free. Muscle memory is a wonderful, wonderful thing.

There are a couple of things I love about VoodooPad : it gets out of my way. I type, I link, I paste in graphics. Gus has obviously paid a lot of attention to the fine details and the app just gets out of my way. It is also very stable. I don’t remember when my last crash was. It just works. Just about every Leopard update makes SnapZ pro freak out and I have to get get new license keys (and then usually something fails on the server side, and takes 20 minutes of dinking around to get a license). Omnigrackle’s layers get confused and the PDF export dialog has a bug that makes it easy to corrupt your document. Mail.app regularly crashes. But VoodooPad just keeps on chugging along. Oh, and it’s fast, too.
Some folks I know put everything into a single VoodooPad document and use it to store their life (or at least their brains). I typically have one VoodooPad document per project, which usually fall int into one of three broad categories:
Design Document : I have one where I keep my design notes for the Extreme Cross Stitch Design software I’m working on for the Spousal Overunit. I dump figures from OmniGrackle in there, and use class names as the currency of links. This makes it very easy to capture my thinking about the specifics of individual classes, as well as highlighting the interactions between classes. Sometimes I can go for a month or two between working on the App, so having all this stuff handy and interlinked makes it easy to reload my mental state. My winning IronCoder entry included a VoodooPad design document with all sorts of notes. (The entry was Race Against Time, if you’re really bored)
Data Dump and Organizer : I have another one where I keep all my notes, to-dos, transcriptions, and copies of interesting emails for the next edition of AMOSXP. You can see a screenie for this is over to the right. I blort in anything and everything I think might be interesting for the next edition. As I start chewing up a chapter, I have ready access to stuff to consider for exclusion (and stuff to nuke). Sometimes one topic (say an extension to a favorite object-oriented language) is too big for one chapter, so something like its automated memory management technique would make better sense living in the Memory chapter. So I can easily make a note in MemoryChap to say “go look over InThisSetOfNotes for these aspects of rubbish aggregation that would be interesting to talk about here”
Debugging Aid : For projects where I tend to do more debugging than design, I have a VoodooPad document that keeps my debugging notes. Usually for each non-trivial problem there’s a page with a dialog with myself. “So What’s the Problem Fool? Oh, Google Kipple is crashing when you frobulate the giznat. Does it happen all the time? No, just on the second launch. Maybe it’s the SpicyPonyHead user preference Hrm, could be” The dialog format lets me focus my thoughts by making explicit what the next useful piece of information might be, and it makes for easier reading when I need to revisit a bug or if I have to put it down for awhile and return to it later. The linky nature of a wiki makes it easy to put in different branches of investigation and let me revisit what I originally thought was a dead end, but might actually be the path to figuring out the real problem. Because Cocoa class names are CamelCapStyle, class names in stack trace become links. Ppaste in a stack trace and then link out to a class to jot down some relevant notes.
I’m a fan. Check it out.
Steve Yegge knows hiring. His latest epistle is Ten Tips for a (Slightly) Less Awful Resume.
Rands also has a new article about The Button, the personality types you’ll run into during technical interviews.
It’s interesting to see common subjects come up in the IRC channels. When someone unfamiliar joins and asks the question “how do I put a method into a function pointer?”, 9 times out of 10 they’re actually wanting to use Cocoa with an existing C API that uses callbacks. A much better question would be “I’m using a C API that uses callbacks with Cocoa, how do I make it work?”
You can’t use Objective-C methods as callbacks. Stop trying, you’ll just make yourself angrier. You have to bounce off of a regular C function, and use any “userData” or “info” mechanism in your C API to pass a pointer to your object.
So assuming you have a call SetDrawingCallback, which takes a function, but you actually want to draw using your objecty-goodness OblateSphereoid object, you would do something like this:
BWOblateSphereoid *egg = [[BWOblateSphereoid alloc] init];
SetDrawingCallback (drawingContext, /* context that wants to draw */
drawEggThunk, /* the function that the context will call */
egg); /* arbitrary userData pointer */
Then in your callback function:
void drawEggThunk (DrawingContext *context, Rect areaToDraw, void *userData)
{
BWOblateSphereoid *dealie = (BWOblateSphereoid *)userData;
[dealie drawAnEggInRect: areaToDraw];
} // drawEggThunk
You are allowed to call Objective-C methods in a C function. You just need to make sure your file is compiled as Objective-C, whether you have a .m extension, or tell Xcode to compile it as Objective-C explicitly. If your callback API doesn’t let you pass in a userData pointer (a rock to hide your data under), you’ll have to put your object into some global location for your C function to find.
If you need to poke inside of the object directly, you can put this function inside of the @implementation block of your class, and then you can access instance variables with the C arrow operator. But that’s kind of naughty, so to preserve your Purity of Essence you should be using method calls on your object. End of Sermon. Here’s the evil:
@implementation OblateSphereoid
void drawEggThunk (DrawingContext *context, Rect areaToDraw, void *userData)
{
BWOblateSphereoid *dealie = (BWOblateSphereoid *)userData;
dealie->_frognatz = [NSColor plaidColor];
// and more stuff.
} // drawEggThunk
…
@end // OblateSphereoid
So why can’t you just (somehow) get the address of -drawAnEggInRect: for the BWOblateSphereoid class and pass that for the drawing callback? The answer is a secret. Two of them, in fact.
When you use brackets in Objective-C to send a message to an object, the compiler is actually generating a call to the C function objc_msgSend (or to one of its variants, but let’s keep it simple):
id objc_msgSend(id self, SEL op, ...);
So something like [egg drawAnEggInRect: someRect] turns into:
objc_msgSend (egg, @selector(drawAnEggInRect:), someRect);
Which then calls drawAnEggInRect:, which under the covers boils down to something like this:
void drawAnEggInRect(id self, SEL selector, Rect someRect) ...
self and the selector are passed in as secret hidden parameters, and then any arguments for the method follow them. This is why you can’t just use the address for a method’s code in a C callback API. The library code invoking the callback will be wanting to put its own stuff in the first couple of arguments, which will cause all sorts of nifty explosions when Objective-C starts interpreting those as object pointers and selectors.
Another fine day on IRC. An individual was stating that you couldn’t pass C arrays to Objective-C methods. That surprised me, so I wrote a little little command line program to check (the program is at lisppaste.) Of course, it turns out you can - Objective-C is still just C. And because it’s just C, you have the behavior of arrays and pointers being pretty much interchangeable.
For instance, you can pass a C array to a method:
- (void) ookie: (int *) snork {
NSLog (@"%d %d %d", snork[0], snork[1], snork[2]);
} // ookie
Or use the [] syntax:
- (void) ookie2: (int[]) snork;
or use the explicit size syntax (which doesn’t really matter for 1-D arrays):
- (void) ookie3: (int[17]) snork;
And you can pass in pointers to pointers to pass back a resized array originally allocated by malloc:
- (void) ookie4: (int**) snork
growTo: (int) elements {
*snork = realloc(*snork, sizeof(int) * elements);
(*snork)[0] = 55;
NSLog (@”(%d) %d %d %d”, sizeof(snork), (*snork)[0], (*snork)[1], (*snork)[2]);
} // ookie4
Passing in arrays of Objective-C types isn’t a problem either:
- (void) ookie: (NSString **) snork {
NSLog (@"%@ %@", snork[0], snork[1]);
} // ookie
Just make sure your syntax is declaring the original array is good:
NSString *blargh[] = { @”oop”, @”ack” };
(the original poster had confusion about Objective-C objects needing to be pointers, having a declaration of NSColor blargh[] = { … }; and then stating that things aren’t possible)
It does go without saying that you should prefer NSArray, or another collection class, to naked C arrays. Sometimes you need to use the lower-level mechanisms, so the power (and pain) is there if needed.