From 2100eff0544e69b7cf02f40555c4dc83bc05c868 Mon Sep 17 00:00:00 2001 From: pengfeizhou Date: Wed, 6 Jan 2021 11:56:30 +0800 Subject: [PATCH] feat:avoid iOS dealloc JSValue in main thread,this may cause crash in JavaScriptCore --- doric-iOS/Example/Example/ViewController.m | 1 + .../Pod/Classes/Plugin/DoricNavigatorPlugin.m | 2 +- .../Pod/Classes/Shader/DoricFlowLayoutNode.m | 5 +++-- doric-iOS/Pod/Classes/Shader/DoricListNode.m | 5 +++-- doric-iOS/Pod/Classes/Shader/DoricSliderNode.m | 5 +++-- doric-iOS/Pod/Classes/Util/DoricAsyncResult.h | 4 +++- doric-iOS/Pod/Classes/Util/DoricAsyncResult.m | 15 +++++++++++++++ 7 files changed, 29 insertions(+), 8 deletions(-) diff --git a/doric-iOS/Example/Example/ViewController.m b/doric-iOS/Example/Example/ViewController.m index 09108518..7047cd51 100644 --- a/doric-iOS/Example/Example/ViewController.m +++ b/doric-iOS/Example/Example/ViewController.m @@ -23,6 +23,7 @@ @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; self.title = @"Doric Demo"; + [self.navigationController.navigationBar setBackgroundImage:UIImageWithColor(UIColor.whiteColor) forBarMetrics:UIBarMetricsDefault]; NSString *path = [[NSBundle mainBundle] bundlePath]; NSString *demoPath = [path stringByAppendingPathComponent:@"src"]; NSFileManager *mgr = [NSFileManager defaultManager]; diff --git a/doric-iOS/Pod/Classes/Plugin/DoricNavigatorPlugin.m b/doric-iOS/Pod/Classes/Plugin/DoricNavigatorPlugin.m index b7e4e1cc..1497bc80 100644 --- a/doric-iOS/Pod/Classes/Plugin/DoricNavigatorPlugin.m +++ b/doric-iOS/Pod/Classes/Plugin/DoricNavigatorPlugin.m @@ -62,4 +62,4 @@ - (void)openUrl:(NSString *)urlString withPromise:(DoricPromise *)promise { }]; }); } -@end \ No newline at end of file +@end diff --git a/doric-iOS/Pod/Classes/Shader/DoricFlowLayoutNode.m b/doric-iOS/Pod/Classes/Shader/DoricFlowLayoutNode.m index 8eb21f64..232f2fca 100644 --- a/doric-iOS/Pod/Classes/Shader/DoricFlowLayoutNode.m +++ b/doric-iOS/Pod/Classes/Shader/DoricFlowLayoutNode.m @@ -237,8 +237,9 @@ - (NSDictionary *)itemModelAt:(NSUInteger)position { return [self subModelOf:viewId]; } else { DoricAsyncResult *result = [self callJSResponse:@"renderBunchedItems", @(position), @(self.batchCount), nil]; - JSValue *models = [result waitUntilResult]; - NSArray *array = [models toArray]; + NSArray *array = [result waitUntilResult:^(JSValue *models) { + return [models toArray]; + }]; [array enumerateObjectsUsingBlock:^(NSDictionary *obj, NSUInteger idx, BOOL *stop) { NSString *thisViewId = obj[@"id"]; [self setSubModel:obj in:thisViewId]; diff --git a/doric-iOS/Pod/Classes/Shader/DoricListNode.m b/doric-iOS/Pod/Classes/Shader/DoricListNode.m index 8e5bbf33..ce0c5bc9 100644 --- a/doric-iOS/Pod/Classes/Shader/DoricListNode.m +++ b/doric-iOS/Pod/Classes/Shader/DoricListNode.m @@ -178,8 +178,9 @@ - (NSDictionary *)itemModelAt:(NSUInteger)position { batchCount++; } DoricAsyncResult *result = [self callJSResponse:@"renderBunchedItems", @(start), @(batchCount), nil]; - JSValue *models = [result waitUntilResult]; - NSArray *array = [models toArray]; + NSArray *array = [result waitUntilResult:^(JSValue *models) { + return [models toArray]; + }]; [array enumerateObjectsUsingBlock:^(NSDictionary *obj, NSUInteger idx, BOOL *stop) { NSString *thisViewId = obj[@"id"]; [self setSubModel:obj in:thisViewId]; diff --git a/doric-iOS/Pod/Classes/Shader/DoricSliderNode.m b/doric-iOS/Pod/Classes/Shader/DoricSliderNode.m index b740d5c9..0fac9f34 100644 --- a/doric-iOS/Pod/Classes/Shader/DoricSliderNode.m +++ b/doric-iOS/Pod/Classes/Shader/DoricSliderNode.m @@ -164,8 +164,9 @@ - (NSDictionary *)itemModelAt:(NSUInteger)position { return [self subModelOf:viewId]; } else { DoricAsyncResult *result = [self callJSResponse:@"renderBunchedItems", @(index), @(self.batchCount), nil]; - JSValue *models = [result waitUntilResult]; - NSArray *array = [models toArray]; + NSArray *array = [result waitUntilResult:^(JSValue *models) { + return [models toArray]; + }]; [array enumerateObjectsUsingBlock:^(NSDictionary *obj, NSUInteger idx, BOOL *stop) { NSString *thisViewId = obj[@"id"]; [self setSubModel:obj in:thisViewId]; diff --git a/doric-iOS/Pod/Classes/Util/DoricAsyncResult.h b/doric-iOS/Pod/Classes/Util/DoricAsyncResult.h index 6a5b6a7d..1811df1d 100644 --- a/doric-iOS/Pod/Classes/Util/DoricAsyncResult.h +++ b/doric-iOS/Pod/Classes/Util/DoricAsyncResult.h @@ -24,7 +24,6 @@ NS_ASSUME_NONNULL_BEGIN - @interface DoricAsyncResult : NSObject @property(nonatomic, strong) void (^resultCallback)(R result); @property(nonatomic, strong) void (^exceptionCallback)(NSException *e); @@ -39,6 +38,9 @@ NS_ASSUME_NONNULL_BEGIN - (R)getResult; - (R)waitUntilResult; + +- (id)waitUntilResult:(id (^)(R result))transformer; + @end NS_ASSUME_NONNULL_END diff --git a/doric-iOS/Pod/Classes/Util/DoricAsyncResult.m b/doric-iOS/Pod/Classes/Util/DoricAsyncResult.m index fd3257dc..04652cb1 100644 --- a/doric-iOS/Pod/Classes/Util/DoricAsyncResult.m +++ b/doric-iOS/Pod/Classes/Util/DoricAsyncResult.m @@ -89,4 +89,19 @@ - (id)waitUntilResult { dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); return self.result; } + + +- (id)waitUntilResult:(id (^)(id result))transformer { + if (self.result) { + return transformer(self.result); + } + __block id ret = nil; + dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); + self.resultCallback = ^(id r) { + ret = transformer(r); + dispatch_semaphore_signal(semaphore); + }; + dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); + return ret; +} @end