The two approaches use different methods:
A) fishhook works, as you have stated, on symbols in the symbol table. This means that, if a symbol is exported by a dylib or framework, and you can patch the import table, you can redirect it to your implementation.
B) mach_override uses the Mach VM APIs of OS X (and iOS) to patch the functions when they are already loaded - i.e. already in memory. It does so by binary patching the beginning of the function implementation to jump to another address (your implementation) then jump back.
Fishhook is more stable, in the sense that it is (i) an easier operation to implement and (ii) seamless once the process is loaded by dyld and the symbols are linked. However, it will not work on symbols which are not directly loaded by the executable. In other words, if you want to patch printf(3), for example, it will only work on calls to printf from your executable, and not on calls made from libSystem, or other libraries. Mach_override, however, is not all that stable, however, since it relies on certain function prologs which can be overridden - some 90% of the time, but not 100%.
While yiding is correct about iOS pages being read only, in some cases it may be possible to work around that (if you patch the executable you can also patch the LC_SEGMENT and section commands), and you can use the mach VM apis to unprotect pages (only if the device is jailbroken).