6

UITableView のサブクラスを作成しています。サブクラスで UITableViewDelegate メソッド自体の一部を処理してから、それらを「実際の」デリゲートに渡し、サブクラスによって実装されていないすべての UITableViewDelegate メソッドを転送する必要があります。

サブクラスには、プライベート プロパティがあります。

@property (nonatomic, assign) id <UITableViewDelegate> trueDelegate;

これは、実装されていないすべてのメソッドが転送する必要がある「実際のデリゲート」を保持します。私が設定した両方のinitメソッドで

self.delegate = self;

そして私はオーバーライドします - (void)setDelegate:(id) このように

-(void)setDelegate:(id<UITableViewDelegate>)delegate {
    if (delegate != self) {
        _trueDelegate = delegate;
    } else {
        [super setDelegate:self];
    }
}

次に、これらをオーバーライドしてメッセージ転送を処理します

-(NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector {
    NSMethodSignature *sig;
    sig = [[self.delegate class] instanceMethodSignatureForSelector:aSelector];
    if (sig == nil) {
        sig = [NSMethodSignature signatureWithObjCTypes:"@^v^c"];
    }
    return sig;
}

- (void)forwardInvocation:(NSInvocation *)anInvocation {
    SEL selector = anInvocation.selector;
    if ([self respondsToSelector:selector]) {
        [anInvocation invokeWithTarget:self];
    } else {
        [anInvocation invokeWithTarget:_trueDelegate];
    }
}

問題は、実装されていないデリゲート メソッドがテーブルビューで呼び出されないため、_trueDelegate オブジェクトに転送される機会が与えられないことです。

ここでそれらをチェックしてみました:

- (BOOL)respondsToSelector:(SEL)aSelector {

}

ただし、そのメソッドは UITableViewDelegate メソッドに対して呼び出されることはありませんが、他のメソッドは問題なくキャッチされます。

4

1 に答える 1

12

パフォーマンスのためにUITableView、デリゲートが設定されるとすぐに、どのデリゲート メソッドが使用可能かをチェックして記憶します。最初にデリゲートを設定しself、次にtrueDelegate. そのため、デリゲートがUITableViewtrueDelegateisnilなどに設定された時点で、-respondsToSelector:常に が返されますNO

これを修正するには、設定後にデリゲートをtrueDelegate設定します。また、転送コードを簡素化できます。プロパティを除く上記のすべてのコードを削除し、次のものに置き換えます。

- (void)setDelegate:(id <UITableViewDelegate>)delegate
{
    if (delegate == self) return;

    self.trueDelegate = delegate;
    [super setDelegate:self];
}

- (BOOL)respondsToSelector:(SEL)aSelector
{
    if ([super respondsToSelector:aSelector]) return YES;

    return [self.trueDelegate respondsToSelector:aSelector];
}

- (id)forwardingTargetForSelector:(SEL)aSelector
{
    return self.trueDelegate;
}
于 2012-07-13T23:57:09.387 に答える