From 4b9695ff501bbbf8f079b498a88013b148ad64cd Mon Sep 17 00:00:00 2001 From: cacaodev Date: Thu, 24 Mar 2011 18:40:25 +0100 Subject: [PATCH] cache respondsToSelector: ; Fire the timer only if both methods exists --- AppKit/CPScrollView.j | 50 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 41 insertions(+), 9 deletions(-) diff --git a/AppKit/CPScrollView.j b/AppKit/CPScrollView.j index 348185974..1e3fde79b 100644 --- a/AppKit/CPScrollView.j +++ b/AppKit/CPScrollView.j @@ -35,7 +35,10 @@ contents of the view. */ -var TIMER_INTERVAL = 0.2; +var TIMER_INTERVAL = 0.2, + CPScrollViewDelegate_scrollViewWillScroll_ = 1 << 0, + CPScrollViewDelegate_scrollViewDidScroll_ = 1 << 1; + @implementation CPScrollView : CPView { @@ -43,7 +46,8 @@ var TIMER_INTERVAL = 0.2; CPClipView _headerClipView; CPView _cornerView; CPView _bottomCornerView; - id _delegate @accessors(property=delegate); + + id _delegate; CPTimer _scrollTimer; BOOL _hasVerticalScroller; @@ -53,7 +57,8 @@ var TIMER_INTERVAL = 0.2; CPScroller _verticalScroller; CPScroller _horizontalScroller; - int _recursionCount; + CPInteger _recursionCount; + CPInteger _implementedDelegateMethods; float _verticalLineScroll; float _verticalPageScroll; @@ -104,11 +109,34 @@ var TIMER_INTERVAL = 0.2; _delegate = nil; _scrollTimer = nil; + _implementedDelegateMethods = 0; } return self; } +- (id)delegate +{ + return _delegate; +} + +- (void)setDelegate:(id)aDelegate +{ + if (aDelegate === _delegate) + return; + + _delegate = aDelegate; + _implementedDelegateMethods = 0; + + if (_delegate === nil) + return; + + if ([_delegate respondsToSelector:@selector(scrollViewWillScroll:)]) + _implementedDelegateMethods |= CPScrollViewDelegate_scrollViewWillScroll_; + + if ([_delegate respondsToSelector:@selector(scrollViewDidScroll:)]) + _implementedDelegateMethods |= CPScrollViewDelegate_scrollViewDidScroll_; +} // Calculating Layout + (CGSize)contentSizeForFrameSize:(CGSize)frameSize hasHorizontalScroller:(BOOL)hFlag hasVerticalScroller:(BOOL)vFlag borderType:(CPBorderType)borderType @@ -661,8 +689,8 @@ var TIMER_INTERVAL = 0.2; } [self _sendDelegateMessages]; - - [_contentView scrollToPoint:contentBounds.origin]; + + [_contentView scrollToPoint:contentBounds.origin]; } /* @ignore */ @@ -1037,15 +1065,18 @@ var TIMER_INTERVAL = 0.2; contentBounds.origin.y += aSize.height; [_contentView scrollToPoint:contentBounds.origin]; - [_headerClipView scrollToPoint:CGPointMake(contentBounds.origin.x, 0)]; + [_headerClipView scrollToPoint:CGPointMake(contentBounds.origin.x, 0)]; } - (void)_sendDelegateMessages { + if (_implementedDelegateMethods == 0) + return; + if (!_scrollTimer) { [self _scrollViewWillScroll]; - _scrollTimer = [CPTimer scheduledTimerWithTimeInterval:TIMER_INTERVAL target:self selector:@selector(_scrollViewDidScroll) userInfo:nil repeats:YES]; + _scrollTimer = [CPTimer scheduledTimerWithTimeInterval:TIMER_INTERVAL target:self selector:@selector(_scrollViewDidScroll) userInfo:nil repeats:YES]; } else [_scrollTimer setFireDate:[CPDate dateWithTimeIntervalSinceNow:TIMER_INTERVAL]]; @@ -1053,7 +1084,7 @@ var TIMER_INTERVAL = 0.2; - (void)_scrollViewWillScroll { - if ([_delegate respondsToSelector:@selector(scrollViewWillScroll:)]) + if (_implementedDelegateMethods & CPScrollViewDelegate_scrollViewWillScroll_) [_delegate scrollViewWillScroll:self]; } @@ -1062,7 +1093,7 @@ var TIMER_INTERVAL = 0.2; [_scrollTimer invalidate]; _scrollTimer = nil; - if ([_delegate respondsToSelector:@selector(scrollViewDidScroll:)]) + if (_implementedDelegateMethods & CPScrollViewDelegate_scrollViewDidScroll_) [_delegate scrollViewDidScroll:self]; } @@ -1118,6 +1149,7 @@ var CPScrollViewContentViewKey = @"CPScrollViewContentView", _delegate = nil; _scrollTimer = nil; + _implementedDelegateMethods = 0; // Do to the anything goes nature of decoding, our subviews may not exist yet, so layout at the end of the run loop when we're sure everything is in a correct state. [[CPRunLoop currentRunLoop] performSelector:@selector(_updateCornerAndHeaderView) target:self argument:_contentView order:0 modes:[CPDefaultRunLoopMode]]; }