20

I was using method swizzling to wrap all method invocations in a class with some extra functionality. Specifically I was:

  • Checking if the required object for this method call was in the cache
  • If the cache had that object return it.
  • If not, dispatch to the original implementation, populate the cache and return that.

For each method, I would reroute to an advised method. And implement the new method using + (BOOL)resolveInstanceMethod:(SEL)sel and IMP_implementationWithBlock.

It worked fine, but the code didn't read nicely. It seems NSProxy will provide a neater way to implement this functionality.

But still another alternative, would be to simply have an NSObject subclass stand-in and intercept method calls around my target object's methods. By overriding forwardInvocation and methodSignatureForSelector, I can get the required outcome.

So what does NSProxy give me? Why should I use this instead?

Jasper Blues
  • 28,258
  • 22
  • 102
  • 185

1 Answers1

16

The point of NSProxy is that it doesn't implement most methods. That's necessary to be sure that the Objective-C forwarding machinery gets invoked to begin with. If you start with NSObject, there are a lot of methods which will just be directly dispatched without you having an opportunity to forward them.

Ken Thomases
  • 88,520
  • 7
  • 116
  • 154
  • 2
    Can you be more specific? Under what circumstances? I've implemented a proxy and it works whether I extend NSProxy or not. – Jasper Blues Aug 17 '13 at 07:12
  • Look at the interface of `NSObject`. Any of the methods defined there that are neither defined in `NSProxy` nor overridden by your proxy class will not be forwarded. Be sure to also consider all categories on `NSObject` (those with implementations, not informal protocols). One example might be `-classForCoder` and friends. What happens if you try to archive an `NSString` wrapped in your proxy class? – Ken Thomases Aug 17 '13 at 18:41
  • Ah. . I was under the impression that it just came down to the result of -methodSignatureForSelector – Jasper Blues Aug 18 '13 at 04:16
  • 5
    No. First of all, `-methodSignatureForSelector:` doesn't determine anything about which implementation is invoked. It just describes the metadata about the method's signature – its argument count, types, and return type. Second, it's not invoked in "normal" message dispatch. It's only invoked if normal method lookup failed, `+resolveInstanceMethod:` didn't add the method, and `-forwardingTargetForSelector:` doesn't return a valid target. That's my whole point. The forwarding machinery doesn't get invoked if there's already an implementation of the method on the object's class. – Ken Thomases Aug 18 '13 at 05:27
  • 2
    I find this also helpful. http://stackoverflow.com/questions/4574465/objective-c-respondstoselector-question/4574563#4574563 – huggie Nov 02 '13 at 03:17