Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>I'm assuming you don't control the implementation of the class whose method you want to intercept, and so changing the API as @Conrad Shultz suggests isn't feasible. There are several other approaches that come to mind.</p> <p>The first is method swizzling. The way this works is you add a method with the same signature to the class using a category, then you swap the implementations of the method you want to intercept and the method you added. The method you add will call whatever hooks you want before and/or after calling through to "itself." Since you swap the implementations, calling "itself" actually calls the original method. There are plenty of good explanations of method swizzling out there. <a href="http://www.mikeash.com/pyblog/friday-qa-2010-01-29-method-replacement-for-fun-and-profit.html">Here's one.</a></p> <p>Another option might be to wrap the object in an NSProxy and pass calls through using <code>-forwardInvocation</code>. Again there are many resources out there explaining proxies and invocation forwarding in detail, so I won't rehash it here. <a href="http://www.mikeash.com/pyblog/friday-qa-2009-03-27-objective-c-message-forwarding.html">Here's one.</a> This approach is limited in that you have to have the necessary access to swap in your proxy for the real object. If the object is created privately inside some API, then this approach won't be useful.</p> <p>Another approach is to do what KVO does. Key-Value Observing works by creating a subclass of an class at runtime and then doing what's called <code>isa</code>-swizzling to change the class of the existing instance to the new dynamic subclass. There's no reason you couldn't create a runtime-generated subclass of the class whose instance method you want to intercept, and then have your runtime-generated subclass's implementation of that method call out to whatever other hooks before and/or after calling the superclass's (real) implementation of the method. This has the potential to let you intercept more than just one method more easily, but there's not going to be a straightforward way to intercept arbitrary methods with arbitrary signatures, because you've got to figure out a way to call your hooks without mangling the stack, and then vector off into the primary implementation. Intercepting arbitrary methods with arbitrary signatures this way would likely involve writing the trampolines in assembly and then tail calling into the real implementation, like objc_msgSend does. Here's a <a href="http://www.mikeash.com/pyblog/friday-qa-2010-11-19-creating-classes-at-runtime-for-fun-and-profit.html">good article on runtime subclassing</a>.</p> <p>For historical perspective: there also used to be a feature called poseAsClass that would also allow this but it has been removed, I think since SnowLeopard-ish timeframe, so it's probably a non-starter.</p> <p>Any of these options are going to have performance implications and are all exceedingly "clever". I don't say that to pat myself on the back -- I didn't come up with any of these, only regurgitated them. But I've noticed over the years that when a solution feels overly "clever", it's a telltale sign that I'm headed for eventual disaster. Put differently, if the API you're working with doesn't give you a means to intercept these method calls, it's probably a sign that you should approach the problem from a different angle. But your mileage may vary, obviously.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload