forwardInvocation不转发调用

时间:2013-06-18 09:48:10

标签: ios objective-c

我目前正在尝试使用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!
}

1 个答案:

答案 0 :(得分:1)

如果在被调用的类上不存在具有该签名的方法,则仅通过方法分派调用

-forwardInvocation。如果您只是尝试在委托上调用方法,如果委托具有这些方法,但是您希望在类中使用默认实现,则不需要使用-forwardInvocation,只需使用覆盖委托模式。

- (void)doSomething {
    if ([delegate respondsToSelector: @selector(doSomething)]) {
        [delegate doSomething];
        return;
    }
    // ... default behavior
}

如果你真的想要使用一个复杂的形式,其中有一个方法列表来覆盖等,你可能最终会使用NSProxy的子类来前端它并确定哪个类到打电话,但这看起来过于复杂,除非你无法访问你想要修补的课程。