It's obvious that most of the heavy lifting is being done by apple's framework code written in objC, but that doesn't mean it has to be dynamic all the way up. Underneath that is all the BSD C code and device drivers. My device drivers are probably all using manual malloc/free without reference counting... just because they chose to write it that way doesn't mean we have do that in our application logic, and vice versa. That's the power of abstraction.
While I think there are some nice conveniences enabled by dynamic dispatch, like KVO and cocoa bindings, after using them, I find them to be a stringly typed mess.