_UIWebViewScrollView的继承链为:_UIWebViewScrollView->UIWebScrollView->UIScrollView。
通过反编译可以得到实现。_UIWebViewScrollView和UIWebScrollView的实现为:(代码好长,点此跳过)
@interface UIWebScrollView : UIScrollView - (void)didMoveToWindow; - (BOOL)touchesShouldCancelInContentView:(id)arg1; @end
@implementation UIWebScrollView - (void)didMoveToWindow { [super didMoveToWindow]; if (!self.window) { SEL sel = @selector(scrollViewWasRemoved:); if ([super.delegate respondsToSelector:sel]) objc_msgSend(super.delegate, sel, self); } } - (BOOL)touchesShouldCancelInContentView:(id)arg1 { return YES; } @end
@interface _UIWebViewScrollView : UIWebScrollView { _UIWebViewScrollViewDelegateForwarder *_forwarder; BOOL _bouncesSetExplicitly; UIWebBrowserView *_browserView; } - (void)_setWebView:(id)arg1; - (id)delegate; - (void)setDelegate:(id)arg1; - (void)setBouncesHorizontally:(BOOL)arg1; - (void)setBouncesVertically:(BOOL)arg1; - (void)setBounces:(BOOL)arg1; - (void)_weaklySetBouncesHorizontally:(BOOL)arg1; - (void)dealloc; - (id)initWithFrame:(struct CGRect)arg1; @end
@implementation _UIWebViewScrollView - (void)_setWebView:(id)arg1 { [_forwarder setWebView:arg1]; super.delegate = nil; super.delegate = _forwarder; } - (id)delegate { return _forwarder.delegate; } - (void)setDelegate:(id)arg1 { _forwarder.delegate = arg1; super.delegate = nil; super.delegate = _forwarder; } - (void)setBouncesHorizontally:(BOOL)arg1 { [super setBouncesHorizontally:arg1]; _bouncesSetExplicitly = YES; } - (void)setBouncesVertically:(BOOL)arg1 { [super setBouncesVertically:arg1]; _bouncesSetExplicitly = YES; } - (void)setBounces:(BOOL)arg1 { [super setBounces:arg1]; _bouncesSetExplicitly = YES; } - (void)_weaklySetBouncesHorizontally:(BOOL)arg1 { if (!_bouncesSetExplicitly) [super setBouncesHorizontally:arg1]; } - (void)dealloc { [_forwarder release]; _forwarder = nil; [super dealloc]; } - (id)initWithFrame:(struct CGRect)arg1 { self = [super initWithFrame:arg1]; if (self) { _forwarder = [[_UIWebViewScrollViewDelegateForwarder alloc] init]; } return self; } @end
UIWebScrollView比UIScrollView多做了两件事:
- 永远对contentView cancel touch
- 通知delegate自己被移出window的view hierarchy
_UIWebViewScrollView比UIWebScrollView多做了一件事:记录是否被显式设置了Bounces属性。
(UIWebScrollView有其它子类)
_UIWebViewScrollViewDelegateForwarder的实现如下:(代码好长,点此跳过)
@interface _UIWebViewScrollViewDelegateForwarder : NSObject <UIScrollViewDelegate> { id <UIScrollViewDelegate> _delegate; UIWebView *_webView; } @property(nonatomic) UIWebView *webView; // @synthesize webView=_webView; @property(nonatomic) id <UIScrollViewDelegate> delegate; // @synthesize delegate=_delegate; - (void)forwardInvocation:(id)arg1; - (BOOL)respondsToSelector:(SEL)arg1; - (id)methodSignatureForSelector:(SEL)arg1; @end
@implementation _UIWebViewScrollViewDelegateForwarder @synthesize webView=_webView; @synthesize delegate=_delegate; - (void)forwardInvocation:(NSInvocation*)arg1 { SEL sel = [arg1 selector]; bool hasWebViewResponded = false; if ([_webView respondsToSelector:sel]) { [arg1 invokeWithTarget:_webView]; hasWebViewResponded = true; } if([_delegate respondsToSelector:sel]) { [arg1 invokeWithTarget:_delegate]; } else { if (!hasWebViewResponded) { [super forwardInvocation:arg1]; } } } - (BOOL)respondsToSelector:(SEL)arg1 { bool result = [super respondsToSelector:arg1]; if (!result) { result = [_webView respondsToSelector:arg1]; if (!result) { result = [_delegate respondsToSelector:arg1]; } } return result; } - (id)methodSignatureForSelector:(SEL)arg1 { id result = [super methodSignatureForSelector:arg1]; if (!result) { result = [_webView methodSignatureForSelector:arg1]; if (!result) { result = [(NSObject*)_delegate methodSignatureForSelector:arg1]; } } return result; } @end
_UIWebViewScrollViewDelegateForwarder所做的就是把传向_UIWebViewScrollView的消息转发给delegate。这个forwarder的设计可以借鉴到别处,是代理模式的应用吧。