我目前正在尝试使用forwardInvocation
,但遇到了一些麻烦。我想将一组有限方法的ClassA
次调用转发到我ClassB
中作为属性存储的另一个实例(ClassA
),但我也希望在其中有一个回退方法我的ClassA
将在ClassB
。
不幸的是,我发现无论在ClassB
上实施了哪种方法,都会调用ClassA
方法!
我实现这个的方式如下所示。任何人都可以提出任何关于我出错的建议吗?
static NSSet *forwardMessages;
@implementation ClassA
@synthesize classBInstance;
- (id) initWithDelegate:(id)delegate {
self = [super init];
classBInstance = delegate;
return self;
}
+ (void) initialize {
if (self == [ClassA class]) {
forwardMessages = [[NSSet alloc] initWithObjects:
@"doSomething",
@"doSomethingElse",
@"anotherThing",
@"yetMoreThings",
nil];
- (BOOL) respondsToSelector:(SEL)aSelector {
return [super respondsToSelector:aSelector] || [self isHandledByDelegate:aSelector];
}
- (BOOL) isHandledByDelegate:(SEL)aSelector {
return [forwardMessages containsObject:NSStringFromSelector(aSelector)] &&
[classBInstance respondsToSelector:aSelector];
}
- (void)forwardInvocation:(NSInvocation *)anInvocation
{
BOOL forwardThis = [self isHandledByDelegate: [anInvocation selector]];
if (forwardThis) {
[anInvocation invokeWithTarget:classBInstance];
} else {
[super forwardInvocation:anInvocation];
}
}
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector {
Class handlingClass = [self isHandledByDelegate:aSelector]? [classBInstance class]:[self class];
return [handlingClass instanceMethodSignatureForSelector:aSelector];
}
- (void) doSomething {
// this should be forwarded to classBInstance but is always called!
}
答案 0 :(得分:1)
-forwardInvocation
。如果您只是尝试在委托上调用方法,如果委托具有这些方法,但是您希望在类中使用默认实现,则不需要使用-forwardInvocation
,只需使用覆盖委托模式。
- (void)doSomething {
if ([delegate respondsToSelector: @selector(doSomething)]) {
[delegate doSomething];
return;
}
// ... default behavior
}
如果你真的想要使用一个复杂的形式,其中有一个方法列表来覆盖等,你可能最终会使用NSProxy的子类来前端它并确定哪个类到打电话,但这看起来过于复杂,除非你无法访问你想要修补的课程。