Question: Can I intercept a method call in Objective-C? How?

**Edit:**
*Mark Powell*'s answer gave me a partial solution, the *-forwardInvocation* method.
But the documentation states that -forwardInvocation is only called when an object is sent a message for which it has no corresponding method. I'd like a method to be called under all circumstances, even if the receiver does have that selector.

Answer: 
Sending a message in Objective-C is translated into a call of the function `objc_msgSend(receiver, selector, arguments)` or one of its variants `objc_msgSendSuper`, `objc_msgSend_stret`, `objc_msgSendSuper_stret`.

If it was possible to change the implementation of these functions, we could intercept any message. Unfortunately, `objc_msgSend` is part of the Objective-C runtime and cannot be overridden.

By googling I found a paper on Google Books: [A Reflective Architecture for Process Control Applications by Charlotte Pii Lunau](http://books.google.com/books?id=xEdJoKgPHOYC&pg=PA188&lpg=PA188&dq=intercepting+objc_msgsend&source=bl&ots=tc5lMYXHzj&sig=bDLqrSFArDqOEsistOHCS62hVzE&hl=de&ei=-ALnSozvMceG_Abn39SCCA&sa=X&oi=book_result&ct=result&resnum=1&ved=0CAgQ6AEwAA#v=onepage&q=&f=false). The paper introduces a hack by redirecting an object's `isa` class pointer to an instance of a custom MetaObject class. Messages that were intended for the modified object are thus sent to the MetaObject instance. Since the MetaObject class has no methods of its own, it can then respond to the forward invocation by forwarding the message to the modified object.

The paper does not include the interesting bits of the source code and I have no idea if such an approach would have side effects in Cocoa. But it might be interesting to try.
Create a subclass of [`NSProxy`](http://developer.apple.com/mac/library/documentation/cocoa/reference/foundation/Classes/NSProxy_Class/Reference/Reference.html) and implement [`-forwardInvocation:`](http://developer.apple.com/mac/library/documentation/cocoa/reference/foundation/Classes/NSProxy_Class/Reference/Reference.html#//apple_ref/occ/instm/NSProxy/forwardInvocation:) and [`-methodSignatureForSelector:`](http://developer.apple.com/mac/library/documentation/cocoa/reference/foundation/Classes/NSProxy_Class/Reference/Reference.html#//apple_ref/occ/instm/NSProxy/methodSignatureForSelector:) (or [`-forwardingTargetForSelector:`](http://developer.apple.com/mac/library/documentation/cocoa/reference/Foundation/Classes/NSObject_Class/Reference/Reference.html#//apple_ref/occ/instm/NSObject/forwardingTargetForSelector:), if you're simply directing it on to a second object instead of fiddling with the method yourself).

`NSProxy` is a class designed for implementing `-forwardInvocation:` on. It has a few methods, but mostly you don't want them to be caught. For example, catching the reference counting methods would prevent the proxy from being deallocated except under garbage collection. But if there are specific methods on `NSProxy` that you absolutely need to forward, you can override that method specifically and call `-forwardInvocation:` manually. Do note that simply because a method is listed under the `NSProxy` documentation does not mean that `NSProxy` implements it, merely that it is expected that all proxied objects have it.

If this won't work for you, provide additional details about your situation.