From 2b7ff95de616e376cc2968d780feeb588d7d6d21 Mon Sep 17 00:00:00 2001 From: "pengfei.zhou" Date: Wed, 25 Mar 2020 13:30:35 +0800 Subject: [PATCH] iOS:use JSDispatcher to avoid overstock too many js tasks --- .../Pod/Classes/Shader/DoricFlowLayoutNode.m | 21 +++++-- doric-iOS/Pod/Classes/Shader/DoricListNode.m | 21 +++++-- .../Pod/Classes/Shader/DoricScrollerNode.m | 21 +++++-- .../Pod/Classes/Util/DoricJSDispatcher.h | 25 ++++++++ .../Pod/Classes/Util/DoricJSDispatcher.m | 59 +++++++++++++++++++ 5 files changed, 129 insertions(+), 18 deletions(-) create mode 100644 doric-iOS/Pod/Classes/Util/DoricJSDispatcher.h create mode 100644 doric-iOS/Pod/Classes/Util/DoricJSDispatcher.m diff --git a/doric-iOS/Pod/Classes/Shader/DoricFlowLayoutNode.m b/doric-iOS/Pod/Classes/Shader/DoricFlowLayoutNode.m index febea468..3e1bcb7c 100644 --- a/doric-iOS/Pod/Classes/Shader/DoricFlowLayoutNode.m +++ b/doric-iOS/Pod/Classes/Shader/DoricFlowLayoutNode.m @@ -21,6 +21,7 @@ #import "DoricFlowLayoutItemNode.h" #import "DoricExtensions.h" #import +#import "DoricJSDispatcher.h" @protocol DoricFlowLayoutDelegate - (CGFloat)doricFlowLayoutItemHeightAtIndexPath:(NSIndexPath *)indexPath; @@ -174,6 +175,7 @@ @interface DoricFlowLayoutNode () *didScrollBlocks; @property(nonatomic, copy) NSString *onScrollFuncId; @property(nonatomic, copy) NSString *onScrollEndFuncId; +@property(nonatomic, strong) DoricJSDispatcher *jsDispatcher; @end @implementation DoricFlowLayoutNode @@ -384,12 +386,19 @@ - (void)scrollViewDidScroll:(UIScrollView *)scrollView { block(scrollView); } if (self.onScrollFuncId) { - [self callJSResponse:self.onScrollFuncId, - @{ - @"x": @(self.view.contentOffset.x), - @"y": @(self.view.contentOffset.y), - }, - nil]; + if (!self.jsDispatcher) { + self.jsDispatcher = [DoricJSDispatcher new]; + } + __weak typeof(self) __self = self; + [self.jsDispatcher dispatch:^DoricAsyncResult * { + __strong typeof(__self) self = __self; + return [self callJSResponse:self.onScrollFuncId, + @{ + @"x": @(self.view.contentOffset.x), + @"y": @(self.view.contentOffset.y), + }, + nil]; + }]; } } diff --git a/doric-iOS/Pod/Classes/Shader/DoricListNode.m b/doric-iOS/Pod/Classes/Shader/DoricListNode.m index 9a64c8b7..405b6dc4 100644 --- a/doric-iOS/Pod/Classes/Shader/DoricListNode.m +++ b/doric-iOS/Pod/Classes/Shader/DoricListNode.m @@ -23,6 +23,7 @@ #import "DoricListItemNode.h" #import "DoricLayouts.h" #import "DoricRefreshableNode.h" +#import "DoricJSDispatcher.h" @interface DoricTableViewCell : UITableViewCell @property(nonatomic, strong) DoricListItemNode *doricListItemNode; @@ -69,6 +70,7 @@ @interface DoricListNode () @property(nonatomic, strong) NSMutableSet *didScrollBlocks; @property(nonatomic, copy) NSString *onScrollFuncId; @property(nonatomic, copy) NSString *onScrollEndFuncId; +@property(nonatomic, strong) DoricJSDispatcher *jsDispatcher; @end @implementation DoricListNode @@ -264,12 +266,19 @@ - (void)scrollViewDidScroll:(UIScrollView *)scrollView { block(scrollView); } if (self.onScrollFuncId) { - [self callJSResponse:self.onScrollFuncId, - @{ - @"x": @(self.view.contentOffset.x), - @"y": @(self.view.contentOffset.y), - }, - nil]; + if (!self.jsDispatcher) { + self.jsDispatcher = [DoricJSDispatcher new]; + } + __weak typeof(self) __self = self; + [self.jsDispatcher dispatch:^DoricAsyncResult * { + __strong typeof(__self) self = __self; + return [self callJSResponse:self.onScrollFuncId, + @{ + @"x": @(self.view.contentOffset.x), + @"y": @(self.view.contentOffset.y), + }, + nil]; + }]; } } diff --git a/doric-iOS/Pod/Classes/Shader/DoricScrollerNode.m b/doric-iOS/Pod/Classes/Shader/DoricScrollerNode.m index 86239c79..2bc6d14c 100644 --- a/doric-iOS/Pod/Classes/Shader/DoricScrollerNode.m +++ b/doric-iOS/Pod/Classes/Shader/DoricScrollerNode.m @@ -23,6 +23,7 @@ #import "DoricExtensions.h" #import "DoricRefreshableNode.h" #import "DoricPromise.h" +#import "DoricJSDispatcher.h" @implementation DoricScrollView @@ -54,6 +55,7 @@ @interface DoricScrollerNode () @property(nonatomic, copy) NSString *onScrollFuncId; @property(nonatomic, copy) NSString *onScrollEndFuncId; @property(nonatomic, strong) NSMutableSet *didScrollBlocks; +@property(nonatomic, strong) DoricJSDispatcher *jsDispatcher; @end @implementation DoricScrollerNode @@ -144,12 +146,19 @@ - (void)scrollViewDidScroll:(UIScrollView *)scrollView { block(scrollView); } if (self.onScrollFuncId) { - [self callJSResponse:self.onScrollFuncId, - @{ - @"x": @(self.view.contentOffset.x), - @"y": @(self.view.contentOffset.y), - }, - nil]; + if (!self.jsDispatcher) { + self.jsDispatcher = [DoricJSDispatcher new]; + } + __weak typeof(self) __self = self; + [self.jsDispatcher dispatch:^DoricAsyncResult * { + __strong typeof(__self) self = __self; + return [self callJSResponse:self.onScrollFuncId, + @{ + @"x": @(self.view.contentOffset.x), + @"y": @(self.view.contentOffset.y), + }, + nil]; + }]; } } diff --git a/doric-iOS/Pod/Classes/Util/DoricJSDispatcher.h b/doric-iOS/Pod/Classes/Util/DoricJSDispatcher.h new file mode 100644 index 00000000..96c408dd --- /dev/null +++ b/doric-iOS/Pod/Classes/Util/DoricJSDispatcher.h @@ -0,0 +1,25 @@ +/* + * Copyright [2019] [Doric.Pub] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// +// Created by pengfei.zhou on 2020/3/25. +// + +#import +#import "DoricViewNode.h" + +@interface DoricJSDispatcher : NSObject +- (void)dispatch:(DoricAsyncResult *(^)(void))block; +@end \ No newline at end of file diff --git a/doric-iOS/Pod/Classes/Util/DoricJSDispatcher.m b/doric-iOS/Pod/Classes/Util/DoricJSDispatcher.m new file mode 100644 index 00000000..f6dbe3ab --- /dev/null +++ b/doric-iOS/Pod/Classes/Util/DoricJSDispatcher.m @@ -0,0 +1,59 @@ +/* + * Copyright [2019] [Doric.Pub] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// +// Created by pengfei.zhou on 2020/3/25. +// + +#import "DoricJSDispatcher.h" + +@interface DoricJSDispatcher () +@property(nonatomic, strong) NSMutableArray *blocks; +@property(nonatomic, assign) BOOL consuming; +@end + +@implementation DoricJSDispatcher +- (void)dispatch:(DoricAsyncResult *(^)(void))block { + if (!self.blocks) { + self.blocks = [@[block] mutableCopy]; + } else { + while (self.blocks.count > 0) { + [self.blocks removeLastObject]; + } + [self.blocks insertObject:block atIndex:0]; + } + if (!self.consuming) { + [self consume]; + } +} + +- (void)consume { + DoricAsyncResult *(^block )(void) = self.blocks.lastObject; + if (block) { + self.consuming = YES; + [self.blocks removeLastObject]; + DoricAsyncResult *result = block(); + __weak typeof(self) __self = self; + result.finishCallback = ^{ + dispatch_async(dispatch_get_main_queue(), ^{ + __strong typeof(__self) self = __self; + [self consume]; + }); + }; + } else { + self.consuming = NO; + } +} +@end \ No newline at end of file