Note that there are some explanatory texts on larger screens.

plurals
  1. POforwardInvocation to other class instead of instance
    text
    copied!<p>I have a <a href="http://en.wikipedia.org/wiki/Facade_pattern" rel="nofollow">facade</a> singleton that I'd like to forward some class method calls to some "static" class.</p> <p>At first glance, <code>forwardInvocation:</code> appeared to be a possible solution, however, <code>NSInvocation</code>'s <code>invokeWithTarget:</code> and <code>setTarget:</code> only accept an <code>id</code>, i. e. a pointer to an instance, not a class itself. I tried handing over <code>[MyTargetClass class]</code> as the target, but I still get a "No known class method [...]" error when I call <code>[Facade someForwardedMethod]</code> somewhere. When I call <code>[[Facade sharedInstance] someForwardedMethod]</code> I get a "No visible @interface [...] declares the selector [...]" error.</p> <p>Of course I am aware that I also need to override <code>respondsToSelector:</code> and <code>methodSignatureForSelector:</code>, so my code looks like this:</p> <pre><code>- (BOOL)respondsToSelector:(SEL)aSelector { if ([super respondsToSelector:aSelector]) { return YES; } else { return [MyTargetClass respondsToSelector:aSelector]; } } - (NSMethodSignature *)methodSignatureForSelector:(SEL)selector { NSMethodSignature* signature = [super methodSignatureForSelector:selector]; if (!signature) { signature = [MyTargetClass methodSignatureForSelector:selector]; } return signature; } - (void)forwardInvocation:(NSInvocation *)anInvocation { SEL aSelector = [anInvocation selector]; if ([MyTargetClass respondsToSelector: aSelector]) { [anInvocation invokeWithTarget:[MyTargetClass class]]; } else { [super forwardInvocation:anInvocation]; } } </code></pre> <p>Is there a way to make this work, or do I have to choose another approach?</p> <hr> <p>EDIT: I have tried both ways that Rob Napier mentions in his answer, here are my findings:</p> <p>I can call a class method in my target class through the facade instance with</p> <pre><code>[(id)[Facade sharedInstance] doSomethingClassyInTargetClass]; </code></pre> <p>It's a bit uglier than I hoped for, but it works. However, I can not call a class method in my target class when I address the facade class. To quieten the compiler I can write</p> <pre><code>[(Class)[Facade class] doSomethingClassyInTargetClass]; </code></pre> <p>but then it throws an 'NSInvalidArgumentException' "[Facade doSomethingClassyInTargetClass]: unrecognized selector sent to class [...]" at runtime. Apparently the class methods of the facade class get resolved without respect for <code>forwardInvocation:</code>, but after all it has a <code>-</code> in front...</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