NSOperation and NSOperationQueue are available on Leopard or the iPhone to help you parallelize your code. The idea is that if you have code that takes a long time to execute, you create an NSOperation subclass, override main, and put your long running code in there:
@implementation CalculatePiOperation
- (void)main
{
// Calculate PI to 1,000,000 digits
}
@end
To execute an operation, you typically add it to an NSOperationQueue:
NSOperationQueue * queue = [[NSOperationQueue alloc] init]; NSOperation * piOperation = [[[CalculatePiOperatin alloc] init] autorelease]; [queue addOperation:piOperation];
If you add multiple operations to a queue, they all execute in parallel on background threads, allowing your main thread to deal with the user interface. The queue will intelligently schedule the number of parallel operations based on the number of CPU cores your users have, thus effectively taking advantage of your users’ hardware.
The only caveat is that the lifetime of an operation is the main method. Once that method returns, the operation is finished and it gets removed from the queue. If you want to use a class that has an asynchronous API, you have to jump through some hoops. Typically you have to play games with the run loop to ensure that the main method doesn’t return prematurely.
While there are times when you want to do this, it can also be a pain. In other cases, you may not be allowed to use the API on a background thread because it is designed to only work on the main thread. Enter concurrent operations.
As I mentioned in a previous post, I was on the Object Oriented Programming episode of the Mac Developer Roundtable. At one point, the discussion turned to the apparent self = [super init] myth and how assigning to self was not needed and should not be done. Here’s a transcript of my response (with a lot of embarrassing “you knows” removed). My actual response can be heard at 54:51 in the podcast:
Yeah, I mean I don’t want to talk about this too much because it really has nothing to do with object oriented programming. But the fact of the matter is
initreturns a value. And Apple’s documentation says you should assignselfto the return value. It’s the rule of the language. It kinda sucks; I wish they didn’t do it, and it’s rarely needed, but that’s how it is. And it’s really not a lot of work to call, to do that, just say “self = [super init]” And I don’t really see any reason not to do it, and I don’t see any reason to recommend people not do to it because it’s the right way.
That’s all I said on the topic mainly because I thought it was off-topic, and others covered the technical details. However, I think it’s an interesting point, so I thought I’d take a moment to elaborate on my response.
Scotty from the Mac Developer Network just released Mac Developer Roundtable, Episode 17, where I was one of the guests invited to talk about object oriented programming. I always hate listening to myself, especially in podcasts like this where I listen and think “Oh, I should have said …” Anyhow, have a listen, and join MDN. Scotty’s truly one of the nicest people in the Mac community and he’s providing a great service. Be sure to support his efforts.
Yeah, I’m a retro gaming junkie, so this one immediately caught my eye: D-Pad Hero. It’s a new game for the Nintendo Entertainment System (NES) that, you guessed it, is inspired by the ever popular Guitar Hero. It’s got four songs you can play along with:
- Sweet Child o’ Mine, Guns N’ Roses
- The Way You Make Me Feel, Michael Jackson
- Harder, Better, Faster, Stronger, Daft Punk
- The Swing of Things, A-Ha
It’s a free download, and you can play it on an NES emulator. It worked great in Nestopia, for me. Chiptune remakes are always fun, and I’d have to say Sweet Child o’ Mine is my favorite song. I haven’t actually played it too much, yet, though.
Vlad, Boris, and Phillipe were kind enough to have me on Cocoacast Talk Episode 25. I talk about all sorts of random stuff, from my background, to how to get started writing code for OS X, and my open source code. I get to plug Textcast a bit, too.
A few weeks ago, Mike Ash wrote up a fantastic article about thread safety on OS X. Apple’s pushing technologies like NSOperation, currently available on 10.5, and Grand Central, available in the upcoming 10.6 release, in order to help developers utilize all CPU cores and ease the pains of threaded programming, so thread safety is an important topic. One of the key points to his article was the difference between “not thread safe” and “main thread only,” and I think this topic deserves a closer look.
There are two problems with the current state of affairs. First, the documentation is poor. Apple’s API documentation often does not distinguish between “not thread safe” and “main thread only.” The second is that many classes, documented or not, are only safe to use from the main thread.
Both of these problems are important because knowing this information impacts how you write your code. The result is that your architecture is limited to main thread only. Main thread only complicates your code, plus it means you don’t get to use NSOperation or Grand Central at all or to their fullest extent.
Before I delve into some more concrete examples of how the current situation affects architecture, I’d like to discuss why you would ever use multiple threads.
Monday was an exciting day. Wolf and I released version 1.0 of our own application: Textcast. Textcast converts any text to an audio podcast capitalizing on Mac OS X’s built-in text-to-speech conversion. It’s got some killer integration with iTunes. Mac OS X 10.5 Leopard comes with a fantastic new voice: Alex. You’ve got to hear it to believe it. I think Textcast is particularly good for anyone who commutes with an iPod or iPhone (and who doesn’t… heh).
Textcast is being sold under Bit Maki Software, Inc., our joint effort and hopefully the next successful Mac indie company. This is about a year-and-a-half in the making, with some good stories. I’m currently on vacation (perhaps, not the best time to unleash the next world-changing application), so I will write up more when I get home home. In the meantime, buy a copy for the holidays!
I was reading this blog post about the state of Ruby testing, and it introduced some nifty syntax for writing unit tests in Ruby. Instead of using method names as the test name:
def test_separate_invalids_creates_invalid nurse = Nurse.new nurse.separate_invalids! assert_create_invalid_file_for "Job" assert_create_invalid_file_for "JobReport" assert_create_invalid_file_for "JobView" end
You could give each test a string name, like this:
test "separate_invalids! creates invalid file for each model" do nurse = Nurse.new nurse.separate_invalids! assert_create_invalid_file_for "Job" assert_create_invalid_file_for "JobReport" assert_create_invalid_file_for "JobView" end
I wondered if we could do something like this in Objective-C with OCUnit. It turns out it’s possible with some preprocessor magic.
I just posted a binary of Radar Forwarder version 1.0. Radar Forwarder is a small application that handles those rdar:// URLs to Apple Bugs and forwards them to another URL. By default, it’ll forward to the Open Radar website. The application is a faceless background application that is launched on demand and quits after being idle. Once you click past the initial “this application was downloaded from the Internet” warning, it should run transparently and use no resources when not in use.
The application is packaged inside a preference pane due to one snag: if you’ve installed the iPhone SDK, MobileSafari included with the simulator registers for rdar:// links, for some reason. The preference pane allows you to chose which application handles rdar:// links. It also allows you to set the URL to forward to, if you’re so inclined.
Wow, talk about snowball effect. Here’s a tweet I wrote yesterday afternoon:
I’d love to make a public rdar database. I’ve got some ideas on how to implement it. Anyone else interested?
This is something I’ve wanted for a while. Apple’s bug database is not public. All you can see are your own bugs (called “radars” because that’s the name of Apple’s internal bug database tool application), but I’ve always thought it would be nice to be able to see already filed bugs. Maybe someone already filed a bug? Maybe they found a workaround?
I soon got tons of feed back from “Yes” to “We should use {insert your favorite web technology here}”. About five hours after my tweet, Tim Burks (of Nu fame) tweeted that he built a quick prototype on Google’s App Engine:
Here’s a quick start using App Engine: http://openradar.appspot.com
And this morning, I woke up to find more than 85 bugs already entered! Amazing… that’s less than 24 hours from idea proposition to app being built, deployed, and used. I gotta say, I’m ultra impressed with Tim and App Engine. This is my first experience with App Engine and the ability to write and deploy a web app so easily is pretty remarkable.
So head on over to Open Radar and add your own bugs. The bigger the database we get, the more useful it will be. This is still very, very early in development, but I’m ecstatic with the progress thus far.
One note: this does not replace reporting bugs with Apple. You should file all bugs you find, even ones that have already been reported. Apple engineers have repeatedly mentioned that the more duplicates there are, the higher priority a bug becomes. It’s sort of like a voting system. Apple wants to fix the bugs affecting the most people. So lemme reiterate: even if you find a bug in Open Radar before filing it yourself, file it with Apple anyway.
Oh, and the source code to Open Radar is Open Source and Tim posted it up in GitHub. Jump on in and give us a hand.
