我有一个facade单身,我想转发一些类的方法调用一些“静态”类。forwardInvocation而不是实例的其他类
乍一看,forwardInvocation:
似乎是一个可行的解决方案,但是,NSInvocation
的invokeWithTarget:
和setTarget:
只接受一个id
,我。即一个指向实例的指针,而不是一个类本身。我试着交出[MyTargetClass class]
作为目标,但当我拨打[Facade someForwardedMethod]
某处时,我仍然收到“没有已知类方法[...]”错误。当我打电话给[[Facade sharedInstance] someForwardedMethod]
时,我得到一个“No visible @interface [...]声明选择器[...]”错误。
当然,我知道我还需要重写respondsToSelector:
和methodSignatureForSelector:
,所以我的代码如下所示:
- (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];
}
}
有没有一种方法,使这项工作,还是我选择另一种方法?
编辑:我曾尝试罗布纳皮尔提到了他的答案是双向的,这里是我的发现:
我可以通过门面实例调用一个类的方法在我的目标类
[(id)[Facade sharedInstance] doSomethingClassyInTargetClass];
这比我希望的有点丑,但它的工作原理。但是,当我处理Facade类时,我无法在目标类中调用类方法。为了平息编译器,我可以写
[(Class)[Facade class] doSomethingClassyInTargetClass];
但随后抛出“NSInvalidArgumentException”的“[门面doSomethingClassyInTargetClass]:无法识别的选择发送到类[...]”在运行时。显然,门面类的类方法得到解决不尊重forwardInvocation:
,但毕竟它有一个-
在前面...
我是否正确理解您正在尝试将实例调用转发给类?是否有任何理由不让你的Facade也成为单例,这样你就可以将实例调用转发给类实例和类调用? –
其实这将是理想。但是,如果可能的话,将类方法调用转发给其他类就足够了。不应该用相同的代码工作吗?我试过了,但它也不起作用。我相应地修改了这个问题......我想避免实例化另一个类,它很庞大并且没有任何会从中受益的东西。 – Stefan
类对象**是**实例;它是它的元类的一个实例。您可能需要使用强制转换才能说服编译器。另外,你是否尝试过新的快速转发机制'-forwardingTargetForSelector:'? –