How to run an iPhone app in the simulator without using XCode
I spent a lot of time looking around on the Internet for this answer, and the results were basically nonexistent. The answer is: iphonesim on github. (Despite its name, iphonesim isn't an iPhone simulator; you still need the iPhone SDK to be installed so it can use their simulator.)
The bad news is there's no obvious way to run your app in a Debugger using this system. Hopefully someday it'll be added or I'll figure it out, and then I'll be rid of XCode for good.
Why the iPhone Simulator is Awesome
While we're here, I'm very impressed by the whole concept on which the iPhone simulator works. Most embedded devices (including Blackberry, Android, and other phones) use software to emulate the embedded CPU, which then runs the embedded OS, which then runs your app. This kind of sucks, because the emulator has to work really hard (it often runs at only a fraction of the speed of a real device), and if you crash it you have to reboot it. Plus loading apps onto a simulated device is extra crappy, because you have to simulate a slow USB connection, and so on.
The iPhone simulator works nothing like that. Instead, you compile your app for your native CPU, and they made the iPhone simulator just a native program that runs on your workstation and provides the iPhone API (using native libraries). You simulate and test your program, and when you're finally happy with it, you recompile your app for the target CPU that actually runs on an iPhone. Then it won't work on the simulator anymore.
The result is that the simulator starts instantly and there's no insane two-layer debugging scheme in which you're running a native debugger and decoding non-native (and usually JITted) CPU instructions.
Some people would argue that this method is "less accurate" than precisely emulating the target CPU, and thus the simulator doesn't add much value, since you'll have to test the native app in the end anyhow. It's true that simulating this way is inaccurate and you should do final tests on a real device. The misconception, though, is that the old, annoying, slow, "emulate everything" method is any more accurate. In fact, it's worse.
The fact is, emulators are never perfect. CPU/hardware emulators are really hard to get right, especially if you're trying to make them run fast. If you're not trying to make them run fast, you have a whole different set of problems, because now your simulator is way slower than the real device, so all the animations/etc will be wrong. Try debugging an OpenGL app when your framerate is 1/10th what it should be.
By contrast, the iPhone simulator's method seems magically wonderful. Since the iPhone OS is MacOS, all the kernel APIs are the same. The natively-compiled frameworks, libraries, and display engine are built from the same source code, so you know they're the same too. And your Mac's CPU is a lot faster than the iPhone's CPU, so the simulator can slow down your program to iPhone speed, which is a lot easier than speeding it up (although admittedly imperfect).
In fact, with this method, the only potential sources of incorrect simulation are a) speed (which they seem to have gotten right); b) cross-platform bugs in gcc (I don't know of any); or c) differences in memory layout making memory corruption behave differently. (c) could be a problem, but they seem to provide a lot of debugging tools and you shouldn't be depending on memory corruption anyhow.
Incidentally, this design justifies the fact that you have to have a Mac to do iPhone development, and you have to have the latest MacOS (Snow Leopard) to run the latest SDK. This annoyed me when I first heard of it; I thought Apple was just trying to lock more people into buying a Mac. But now it totally makes sense: iPhone OS is Snow Leopard, so if you want to run the native simulator, of course you need Snow Leopard, or the simulator can't possibly work.
That's a really brilliant design tradeoff with huge benefits. And they get to lock more people into buying a Mac.
Update 2010/04/08: A few people have pointed out that the Blackberry "emulator" is apparently not actually an "emulator" but in fact runs a natively-compiled version of the Blackberry JVM. Okay, I guess, but that's not really the point. The point is that it still spends upwards of 30 seconds booting the "virtual Blackberry" before it even gets to the point where you can run your program. (And you have to do this every time you want to run your program.) This is annoying, slow, and pointless, and the (apparently native??) JVM still runs everything horrendously slowly - slower than a real Blackberry. So if it's not a native device emulator, then congratulations, it's somehow even stupider. Yes, I've done real Blackberry development, and the difference between the Blackberry and iPhone simulators is night and day.