CocoaHeads Lake Forest is this Wednesday, the 10th, at 7 PM. If you're attending, let's have dinner at 6 PM at Philly's Best in Lake Forest:
I'm still Mac-only, so I still won't be there, but here's the information for this year:
- The conference is in Seattle, Washington on April 24th and 25th.
- The speakers, including Aaron Hillegass, Jonathan “Wolf” Rentzsch, Erica Sadun, and Eric Buck, will cover many different topics, including Core Data, Core Location and MapKit, in-app purchasing, UI design, and OpenGL ES.
- Early bird pricing is $200 off until March 12th.
- If you use the coupon code “PHBLOGS”, you'll get another $100 off.
(I do still wonder what the “PH” stands for…)
If this sounds good to you, register for the conference.
See also Brent Simmons's post about it. He wants to play pinball with you.
Anyone who's ever had to perform a message on the main thread knows how ugly the code can be:
[obj performSelectorOnMainThread:@selector(receiveAnswer:)
withObject:[NSNumber numberWithUnsignedInteger:42]
waitUntilDone:NO];
I've written a category that changes the above code to something much simpler:
[[obj performOnMainThread_PRH] receiveAnswer:42];
Notice that not only is the code much easier to read and to write, but you no longer need to box and unbox primitive values.
You can get the code, under a BSD license, from the higher-order main-thread perform repository.
Back when I originally mentioned my creation of the category on Twitter, Dave Dribin replied that he had already written one of his own. His is part of his DDFoundation framework, and requires DDInvocationGrabber (a fork of Jonathan Wight's CInvocationGrabber), also part of that framework.
My category requires nothing but Cocoa and is not part of a larger framework. That said, it's interesting to read in his code how the functionality of the Invocation Grabber makes his implementation nothing but a thin wrapper around it. (Also, his version lets you say waitUntilDone:YES.)
Many of you may remember an audio editor named Amadeus II. It turns out that there is a successor to it now, named Amadeus Pro.
One of Amadeus Pro's features is the ability to remove noise, quickly and simply. Find, within the audio, a patch of nothing but noise, and choose “Sample Noise”. This trains the filter for that audio. Then, select the whole thing (or nothing), and choose “Suppress Noise”.
That's it. Sample Noise, then Suppress Noise.
Here's the result, as demonstrated by a 12-second clip from a recording, ripped from cassette, of Haydn's Symphony #49, “La Passione”:
(This is actually from a quiet section; I amplified it before filtering it so that you can hear the hiss at the start.)
That's not to say that it only works on music. I'm also using it on the audio for forthcoming CocoaHeads Lake Forest videos.
This feature alone is worth the $40 for this application.
Before anybody mentions Audacity: Yes, Audacity has a Noise Removal tool, but it lacks the It Just Works factor of Amadeus's noise-remover. Audacity gives you three settings to think about, with names only an audio engineer could love. (“Frequency smoothing”?!) In Amadeus, all you need to tell it is “here's what noise sounds like. Go kill it.” This (plus a native Mac OS X interface) is worth the money to me.
CocoaHeads Lake Forest is this Wednesday, the 10th, at 7 PM. If you're attending, let's have dinner at 6 PM at Philly's Best in Lake Forest:
I originally wrote this as an application using NSImage (with NSImageInterpolationNone), but decided to rewrite it as an Image Unit. So, here it is.
If you know someone who's recently taken up programming the Mac or the iPhone (or both), please give them one (or both) of these links:
As a frequent answerer of questions on Stack Overflow, I see certain patterns—not just frequently-asked questions, but also frequently-unasked questions: Things that are biting the questioner that they don't know about.
Sometimes they're thinking about things the wrong way (e.g., using property list objects where they should have a model). Sometimes there is a route to a solution (“my app is slow” “run Instruments”), but they don't know about that route. Often, they'll use wrong terms that are right on another platform (like “member variable”), like a speaker using their native language's pronunciation rules when speaking a foreign one.
To help people over these speed bumps, I've composed an introduction for new Cocoa and Cocoa Touch programmers. (Both of the above links redirect to it.)
If any part of it doesn't help them (i.e., is unclear or wrong), I'd appreciate it if you'd let me know, either here or by email.
A common question from people new to Objective-C is “why do I have to separately alloc and init? Why can't I just call one thing and get a fully initialized object?”.
It's certainly not how other environments do it. Usually, you call one function or class method, and you get an object. Cocoa makes you send two messages: one to the class, then another to the fresh, uninitialized instance you got back. What does Cocoa know that those other environments don't?
There are two reasons why alloc and init are separate:
-
“NSResponder”* says that sometimes, NeXT wanted to initialize the same object multiple times.
This is interesting, but horrifying to modern readers. Practically all
initmethods I've seen do not handle the case of initializing the already-initialized; they blindly assign newly created/retained objects to the ivars without checking for existing objects there.A bigger problem is when the
initmethod releases the receiver and returns some other object; in the second message, the “other” object may in fact be the receiver (returned from the first message), so[self release]this time would be killing off an object that should stay alive. On the other hand, retaining the object before re-initializing it will create a leak if the object doesn't release itself. Unpredictable behavior is bad. -
On the same Stack Overflow question, Darren points out that
allocis shorthand forallocWithZone:; if allocation and initialization were merged in Cocoa, then, to maintain the same functionality, every initializer would need to take a zone parameter, and optionally come in a flavor without one. You can imagine how a proliferation of initializers would ensue.This is essentially what the documentation says: “Separating allocation from initialization gives you individual control over each step so that each can be modified independently of the other.” I.e., both steps can be customized, so they must remain separate so that you can customize either or both.
So, there are two practical reasons why Cocoa's designers separated allocation from initialization.
But let's revisit this with modern eyes:
- As I mentioned, in modern Cocoa, initializing an instance again is risky at best. In practice, I don't think anybody does it, and if anybody does, they probably feel guilty about it and mean to refactor that code “someday”.
- Nobody uses zones anymore.
That blows those two reasons away.
So, let's imagine what life would be like if they had never existed in the first place, and allocation and initialization had remained one task:
+ (id) newWithFramistan:(Framistan *)framistan {
id obj = [super new];
if (obj) {
obj->framistan = framistan;
}
return obj;
}
Right away, you can see several advantages:
- We can name our local variable “framistan”, not “newFramistan” or anything like that.
- No more assignment in condition (
if ((self = …))). - No more assignment to
self(which should make Wil Shipley happy). - Eliminates the problem of
[super init]returning a different object, whereupon you would have to release the receiver. Since the receiver is the class, there is nothing for the upstream-initialized object to be different from. If the superclass wants to return an existing object, it can just do that. - Related to the first point, we no longer have a name conflict between instance variables and local (especially argument) variables. In
initmethods, we resolve this conflict with style rules, such as the aforementionednewFramistanfor locals orm_framistanfor instance variables; in thisnewWithFramistan:method, the conflict doesn't exist in the first place. - There is never an uninitialized object that the caller could leave lying around. We've all seen (or written) code like
Foo *foo = [Foo alloc]; [foo init];; in this alternate universe, such faux pas are impossible.
There are trade-offs:
- It's one line longer. (Depending on your employers' level of cluefulness, this may be a small advantage.)
- Since you're not in an instance, you have to prefix every instance-variable access with
obj->. I can see how this could get tedious; on the other hand, this is what prevents ivar-vs.-local name conflicts. - If you use object controllers that automatically prepare their content, they'll use
allocandinit, bypassing this initializer. I've never used the automatic-content-preparation feature, so this doesn't affect me. - It'll be less than familiar to anybody who hasn't read this post, and it's certainly a change from currently-typical Cocoa code.
- Doing this in a subclass of a class that has an unusual designated initializer, such as NSView with its
initWithFrame:, could get tricky.
My opinion is mixed. On the one hand, real problems with the init way of doing things are rare for anyone who knows the ropes. On the other hand, it sure is more straightforward, isn't it?
What do you think?
* Presumably the same one most of us recognize as John C. Randolph, although there's no direct evidence of this on his SO profile. ↶
Back in 2006, Valve Software released the trailer for Portal.
Based on that trailer, We Create Stuff created Portal: The Flash Version. The same day they released it, Valve released The Orange Box (Portal being part of it).
The next year, We Create Stuff released the Portal: The Flash Version Map Pack*, which is the levels from Portal: TFV converted to 3D levels in the real Portal.
And then, at E3 a few months later, Microsoft announced “Portal: Still Alive”, which Valve confirmed is Portal plus the Portal: The Flash Version Map Pack.

When posting links on Twitter, your Twitter client will automatically shorten the URLs to make them fit.
There are many, many general shorteners, including TinyURL, Notlong, Metamark, and Bit.ly. One of the complaints about these is that they hide the true destination of the link: From the URL alone, you don't know whether you're going to be educated, RickRolled, or worse. (TinyURL and Bit.ly both offer a way to preview the link, but that's not as easy as just looking at the URL.)
To help with this, several non-shortening-related websites have added their own shorteners that use their own domains, particularly for use on their official Twitter accounts or with a built-in post-to-Twitter feature.
The problem is that it's not always easy to tell what the shortened link will be. Flickr is among the most difficult: Their regular links use decimal numbers, but their shortened links use base-58, which is not a trivial conversion to perform in any programming environment I know how to use. (Not so easy as, say, decimal to octal.) It's certainly doable, but would require extensive tests to verify that your base-58 numbers match Flickr's. There's sample code, but it's in PHP, so if you're writing in anything else, that means porting it, which means (again) extensive tests.
So, rather than write my own shortener, it's much easier to just use Flickr's: curl the canonical long URL, then scrape the short one out of the body. (Yay for <link rev="canonical">!) I wrote a service to do this.
For Ship-It Saturday, I retooled it. No longer is it just a Flickr shortening service: It now handles YouTube, Amazon, and a few other sites as well. A single service invocation shortens all links to websites that have their own shorteners.
So, here you go: The Shorten URLs service.
I've updated my shrine to the Glypha games with even more cool old stuff:
- The stereoscopic space shooter Stella Obscura!
- More old versions of Glider—including version 2.02!
- More source code!
- A link to Kent Sutherland's iPhone version of Glypha!
If you want to play these old games, you'll need Mini vMac and its dependencies. The newer versions of Glypha (and possibly Glider) may require a later-generation emulator. That's assuming, of course, that you don't still have a real, working old Mac.
Deep thanks go to Steve White for contributing a number of the additions. The page would be only half as long without his help.
Steve Smith says “Stop Blogging”:
I mean it. All of you people are writing fantastic, useful articles about code, methods, and technologies, but you’re putting them in blog posts — a date-based format that encourages us to leave things as they were, historically.
This got me to thinking about the difference between two of the tutorials I've published.
The pointers tutorial is a single web page. There's a date stamp, but it's way down at the bottom. The ASL series is nine blog posts.
In the three years since the previous version of the pointers tutorial, dozens of people emailed me to tell me about its major errors.
In the two years since I published the last of the ASL series (ignoring approximately a week afterward), nobody has told me of an inaccuracy in any of the posts.
There are a number of possible explanations for the ASL series receiving fewer (that is, no) corrections:
- That its audience is narrower: Anyone who programs C has to deal with pointers. Only a very few Mac OS X programmers will ever touch ASL.
- That it is less visible: One of these is linked from my home page and plenty of CS course reading lists (exhibits A, B, C, and D), and was linked for a while from the Wikipedia article on the C programming language; the other is practically unknown to anyone who wasn't subscribed to my blog at the time.
- That I'm just that good. (Ha!)
- That ASL hasn't changed at all since Leopard. (Ha!)
Smith writes from the perspective of the author and publisher, who must maintain a web page; he says that the author and publisher finds no (or not much of) such obligation for a blog post. I think the difference in my supply of corrections hints at a reader side to this, although, as shown above, my two examples are hardly comparable.
I have been meaning to move the ASL tutorial into a pointers-style web page at some point, although I don't know when. I may start receiving corrections then, which means I'll have to spend time to fix them. The flip side to that is that if I leave it as blog posts, I'll have that time for other things, but the posts will be consigned to periodically-increasing inaccuracy.
I expect to think more about Smith's suggestion.
There's also the merit of the word “blog”, which is wearing thin for me.
Today's Ship-It Saturday is a command-line interface to the Finder.
The two most useful commands are:
- finder reveal file, which will select the file in a Finder window, and
- finder update (or updated) file, which will tell the Finder that the file has been updated.
The latter command probably is not too useful anymore, but the command-line tool should work on no less than 10.4, and could probably be recompiled for even older versions of Mac OS X, so you may still have a use for it.
The third video of last month's meeting is now up. Here are three easy-to-remember links:
You'll notice that the third video is not CHLF2009Leaks3.
Unlike the other two, this one features Scott Ellsworth, our organizer, demonstrating the Web Inspector in WebKit. He starts off in Safari, then switches over to Chrome. He also talks about a profiling tool that's part of Google Web Toolkit called Speed Tracer, although he wasn't able to finish a demo of it in time for the meeting, so he talks about one of the examples instead.
I don't think I'll link these here anymore. If you want to find out about future CocoaHeads Lake Forest videos, subscribe to the CocoaHeads Lake Forest channel on Vimeo.
This is an expansion of a reply I wrote to a tweet by Daniel Jalkut. He wrote:
Imagine if the iPhone home screen showed a matrix of "generic" icons before filling in real ones. Mac Finder is a disgrace.
He's referring to behavior introduced in Snow Leopard: When you visit a folder for the first time in a session, the Finder shows every symbolic link and alias with the kUnknownFSObject icon (
), every application with the generic application icon, every file with the generic document icon, and every folder with the generic folder icon, before displaying the item's real icon and then its Quick Look thumbnail.
Compare the environment of SpringBoard (on a non-jailbroken device) to that of Finder:
| iPhone | Mac OS X |
|---|---|
|
Every item is of one kind: Application. |
Items are of any of three kinds: File, folder, and bundle. The Finder must handle each kind differently. |
|
Everything is on one iPhone's worth of flash memory. |
Files may be distributed over any number of volumes, local and remote; however, the general case is all files on one hard disk, which is the startup disk. |
|
Because the iPhone doesn't allow background processes, it's the only app running, with only a few built-in, light-on-file-system-access exceptions (the heaviest of which is probably Mail). |
Any number of applications may be running, and they may be accessing files on the same volume you're browsing. |
|
Accessing any file in flash memory is as quick as accessing any other file (random access). |
Disks are not so predictable: Accessing one file and then another can incur milliseconds of seek time. Doing this repeatedly for dozens or hundreds of files (possibly in multiple Finder windows at different scroll positions) may cause the disk to thrash. You can hope that the OS can put the requests into a favorable order, but you can't rely on it, and there's only so much it can do. |
|
Flash memory is always active. |
Most users aren't using flash memory. Hard disks may be spun down to conserve power. If this is the case, the disk will need to be spun up, which can take seconds. |
|
All files (that is, all applications) are local. |
Some volumes may be on remote machines, across a local network or the internet; depending on throughput and latency, every access to such a volume can take tenths of a second. |
|
All applications are in one place, making caching of icons or their filenames easy. |
Applications aren't the only user-visible bundles, and any bundle can be anywhere. |
Compare also how SpringBoard and Finder obtain icons*:
| iPhone | Mac OS X |
|---|---|
|
Assuming that the icons themselves aren't cached:
|
(All of this may happen inside NSWorkspace and/or Icon Services.)
|
SpringBoard hasn't much to do, it's in a straightforward environment, and the task and environment provide a couple of obvious caching strategies. The iPhone doesn't have as much processing power, but what it has is enough—it can just get and display the icon without being lazy about it.
In fact, SpringBoard probably doesn't even need to be asynchronous about it; all it needs to do is keep three pages of icons (current, next, and previous) in short-term memory. When the user flips one page, drop the farthest page out of the short-term memory cache and load the next one into it.
Meanwhile, on the Mac, getting an icon is not straightforward, and the environment can throw a monkey wrench into the works at any point. Every icon can take dozens, hundreds, or thousands of milliseconds to display, and more icons mean more opportunities for a stall. The solution is to load and show the icons asynchronously and in parallel—but then, what to show in the meantime?
Thus, for the Finder, lazy loading makes sense. The Finder can show you what it has (filenames and other basic metadata) immediately. You can work with those files, scroll to other files, or move through the folder hierarchy without having to wait for icons. And while you do that, the Finder has all the time it needs to asynchronously fetch the icons and, if it's still appropriate, display them.
It's a feature, not a bug.
It's been in editing for over a month, but now, it's finally done. I've just uploaded the second part of last month's meeting of CocoaHeads Lake Forest. There's one more to go from last month, and then I can start posting the video from this month.
This one's a lot more random than the first one. Portions of my own presentation are only part of what you'll see in this video.
More long-term, I've created a channel on Vimeo for all past and future CocoaHeads LF videos.
There's a recurring myth going around, which goes something like this:
In fact, using Carbon locks you out of 64 bit.
No, it doesn't.
The truth is that some APIs that are part of the Carbon sub-frameworks are not available in 64-bit. Merely linking against Carbon does not mean your app suddenly stops working in the 64-bit world.
Carbon itself is just an umbrella framework. It doesn't have any APIs that it provides immediately; everything comes from either another framework or one of its sub-frameworks.
Examples of the first category include Core Foundation, Core Services (home of Launch Services), and Application Services (home of Core Graphics). Even these are not immune to the myth, as demonstrated by the comment I linked to above: It's on an answer suggesting a Core Foundation function. The answerer referred to it as a “Carbon function” (true in a sense), and the commenter pounced.
Many things that were once explicitly considered part of Carbon, such as the File Manager and Resource Manager, are now part of Core Services. Note that they haven't even been consigned to the Legacy Library!
In the other category, even some APIs that remain strongly identified with Carbon, by being in a direct sub-framework of Carbon, are still at least partially around. One of these is the Carbon Event Manager, which even has the word Carbon in its name. Try registering a hot-key with it in a 64-bit-only app—it'll work. (That one is in the Legacy Library. I should probably file a bug on that.)
What is deprecated and not available in 64-bit, as you can see in the Carbon Event Manager Reference, is anything that you would need to build your application on Carbon. That's what's deprecated: the concept of a Carbon application. Only Cocoa apps remain.
But some parts of “Carbon” are useful for things other than building a Carbon application. You can use them from a Cocoa application, or from a command-line tool.
Those APIs are still around. They are not deprecated, they are still useful, and they are still available in 64-bit. Use them freely.
(Oh, and before anybody mentions it: No, those NSEvent class methods introduced in Snow Leopard are not direct replacements for Carbon Event Manager hot-keys. You'd have to sift through the events yourself, whereas Carbon Event Manager filters them for you and only calls your function when your key is pressed. The correct analogue would be CGEventTap.)
At long last, a new version of Everything you need to know about pointers.
The most significant changes are long-overdue corrections regarding declarations of const pointers and the difference between arrays and pointers. You can—and, if you learned how to work with pointers from this tutorial, should—read all of the changes in the delta between 1.2 and 1.3.
CocoaHeads Lake Forest is today, the 13th.
I don't have any Philly's Best coupons this time, but I could still go for half a cheesesteak. I eat a basic cheesesteak: Provolone, no onions, no other toppings. If you're up for the other half, raise your hand in the comments, and bring $3 (your half of the price) to the restaurant.
Anyone else will, of course, have to buy their own sandwich.
The place will be the Lake Forest location and the time will be 6 PM—an hour before CocoaHeads.
Some of you know that I use a second-generation iPod nano (the best iPod ever) with an iPod Radio Remote. There are two generations of iPod Remote; here they are side by side:
The original is on the left. It was for the 2G iPod (that's what I had, anyway) and possibly some other models. That remote didn't have a radio tuner in it. The one on the right, the one that has a Dock connector and looks like a 2G iPod shuffle, is the iPod Radio Remote.
The iPod Radio Remote never did work with the iPhone and iPod touch. Every introduction of a new iPhone or iPod touch model (including the originals) made clearer that they'd either make a third generation or kill it. Sometime around the time when they introduced the new Apple Remote, they chose the latter.
At some point, Griffin Technology introduced their Navigate. I spotted one today at Walmart for $20 on clearance and snapped it up. Walmart normally sells it for $50, and MSRP is $60.
Not only does the Navigate work with my 1G iPod touch, it adds a display showing the current track. The iPod Radio Remote never had this! The picture on Griffin's website doesn't do it justice; it actually looks much better, as shown in this video:
(If you want to really see how good it looks, click through to the YouTube page and watch it there.)
Like the Radio Remote, the Navigate has a clip. Unlike the Radio Remote, it's not a moving part; it's just a fixed, flexible (but not too flexible, but not too stiff, either) bit of plastic. Time will tell how easy it is to break.
True to its name, you can even use it to navigate your music: It will let you pick a playlist, artist, or album to listen to, and change the shuffle setting. However, it does not let you go straight to a specific song, which makes that feature useless for me. I understand why that limitation exists, though: It would be much more difficult to scroll to it with the Navigate's buttons than with the iPod's own click wheel or touch screen.
Navigating the FM band isn't exactly easy. When moving along the frequency band itself, next and previous move one frequency-stop at a time. You can set presets, but only four of them. It's not at all obvious how to set and use them; I'll leave it to the manual to explain it. Ameliorating this problem is that it remembers the last station you had tuned, so it's not like you're going to have to deal with the preset menu every time you turn on the radio.
I do have a couple of significant problems with it.
The first is that it doesn't remember your volume setting. (The Navigate has its own volume setting, separate from the iPod's; the iPod's volume setting has no effect on audio through the Navigate. This is another difference from the Radio Remote, which had no volume of its own.) The Navigate doesn't have a battery; it relies on the iPod for power, so it goes dead when you unplug it. Then, when you plug it back in or plug it into a different iPod, it's back to the default volume, which is quite loud for me. This will probably grate on me a bit.
The other problem is that it doesn't fit in my iPod touch's Dock connector with its SeeThru hard case on it. My iPod nano doesn't have a case on it, so I don't have that problem with that iPod. If you don't have a case on your iPhone or iPod touch (or other iPod), or you use a different case that won't conflict with Griffin's Dock connector, then this won't be a problem for you.
I hope a future version of the Navigate will remember the volume setting and have a slightly thinner Dock connector so that it isn't blocked by my iPod touch's case. Even now, though, I consider the Navigate a worthy successor to the iPod Radio Remote, primarily because of the display, secondarily because of the iPod touch (and iPhone) compatibility.

