我有一个门面单例,我想将一些类方法调用转发给一些“静态”类。
乍一看,forwardInvocation:
似乎是一个可能的解决方案,但是,NSInvocation
'sinvokeWithTarget:
并且setTarget:
只接受一个id
,即指向实例的指针,而不是类本身。我尝试将其作为目标移交[MyTargetClass class]
,但是当我在[Facade someForwardedMethod]
某处调用时,仍然会收到“No known class method [...]”错误。当我打电话时,[[Facade sharedInstance] someForwardedMethod]
我收到“没有可见的@interface [...] 声明选择器 [...]”错误。
当然我知道我还需要重写respondsToSelector:
and 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];
}
}
有没有办法使这项工作,还是我必须选择另一种方法?
编辑:我已经尝试了 Rob Napier 在他的回答中提到的两种方式,这是我的发现:
我可以通过外观实例调用目标类中的类方法
[(id)[Facade sharedInstance] doSomethingClassyInTargetClass];
它比我希望的要丑一些,但它确实有效。但是,当我处理外观类时,我无法在目标类中调用类方法。为了让编译器安静,我可以写
[(Class)[Facade class] doSomethingClassyInTargetClass];
但随后它会在运行时抛出一个 'NSInvalidArgumentException' “[Facade doSomethingClassyInTargetClass]: unrecognized selector sent to class [...]”。显然,门面类的类方法在不尊重的情况下得到解决forwardInvocation:
,但毕竟它-
前面有一个......