IOS开发中遇到转发delegate的时候不要再那么傻了

http://sam.dods.co/blog/2014/08/03/secondary-delegate/

delegate代理(截取delegate消息用)

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

@interface MovieSDKDelegateProxy : NSObject <UITableViewDelegate>
@property (nonatomic, weak)id primaryDelegate;
@property (nonatomic, weak)id secondaryDelegate;
@end
@implementation MovieSDKDelegateProxy
- (BOOL)respondsToSelector:(SEL)aSelector {
    return ([self.primaryDelegate respondsToSelector:aSelector] || [self.secondaryDelegate respondsToSelector:aSelector]);
}
- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector
{
    NSObject *delegateForResonse = [self.primaryDelegate respondsToSelector:selector] ? self.primaryDelegate : self.secondaryDelegate;
    return [delegateForResonse respondsToSelector:selector] ? [delegateForResonse methodSignatureForSelector:selector] : nil;
}
- (void)forwardInvocation:(NSInvocation *)invocation
{
    [self invokeInvocation:invocation onDelegate:self.primaryDelegate];
    [self invokeInvocation:invocation onDelegate:self.secondaryDelegate];
}

- (void)invokeInvocation:(NSInvocation *)invocation onDelegate:(id)delegate
{
    if ([delegate respondsToSelector:invocation.selector]) {
        [invocation invokeWithTarget:delegate];
    }
}
@end

use:注意设置每个delegate时必须重新将_proxy设置给tableView的delegate。这样才能保证tableView重新检查delegate支持的方法。(tableView会在设置delegate时将大多数方法都检查一下是否支持,回调时不再检查)

@implementation MovieSDKRefreshTableView {
    MovieSDKDelegateProxy *_proxy;
}
- (instancetype)initWithFrame:(CGRect)frame style:(UITableViewStyle)style {
    self = [super initWithFrame:frame style:style];
    if (self) {
        _proxy = [MovieSDKDelegateProxy new];
        _proxy.primaryDelegate = self;
        [super setDelegate:self];
    }
    return self;
}
- (id<UITableViewDelegate>)delegate {
    return _proxy.secondaryDelegate;
}

- (void)setDelegate:(id<UITableViewDelegate>)delegate {
    _proxy.secondaryDelegate = delegate;
    [super setDelegate:nil]; //Important:must reset delegate, because tableView check all response to @selecter when set delegate
    [super setDelegate:_proxy];
}
@end

 

发表评论

您的电子邮箱地址不会被公开。