Cocoa uses autorelease pool for short-lived objects, so most of the time you don't have to free them.
For long-lived objects you can use synthesized properties which handle retain/release for you.
In other cases you "guard" your use of object with retain/release. You can use these in pairs in the same place, rather than having malloc() in one part of the program, and free() in another.
You can freely pass reference to an object without worrying that you might free it while it's still referenced somewhere else. You don't have to think about ownership of an object.
Indeed. I've become quite enamoured of late with the automatic reference counting in the Boost C++ library as a happy medium between GC and manual reference counting. Of course, ObjC has no static allocation, so that can't be done here.