2013-06-18 2 views
0

В настоящее время я пытаюсь использовать forwardInvocation, но имеет некоторые проблемы. Я хочу направить ClassA вызовы конечного набора методов на другой экземпляр (ClassB), хранящийся как свойство в моем ClassA, но я также хочу иметь метод возврата в моем ClassA, который будет выполнен, если методы не реализованы в ClassB.forwardInvocation not forwarding invocations

К сожалению, я обнаружил, что любые методы, применяемые на 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

-forwardInvocation вызывается только методом отправки, если метод с этой подписи не существует на класс при вызове. Если вы просто пытаетесь вызвать методы делегата, если у делегата есть эти методы, но вы хотите использовать реализации по умолчанию в классе, в противном случае вам не нужно использовать -forwardInvocation, просто используйте шаблон переопределения делегата.

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

Если вы действительно хотите использовать сложную форму, которая имеет этот список методов для переопределения, и т.д., вы, вероятно, будет в конечном итоге, используя подкласс NSProxy к переднему концу его и сделать определение того, какой класс вызывать, но это кажется слишком сложным, если у вас нет доступа к классу, который вы пытаетесь подделать.

+0

Это ответ. Кажется очевидным в ретроспективе. Огромное спасибо! – majackson

Смежные вопросы