From 5a12a770fde1ebd5855f741c1d372f2d9780c485 Mon Sep 17 00:00:00 2001 From: pengfeizhou Date: Mon, 1 Feb 2021 15:31:24 +0800 Subject: [PATCH] iOS:use safe method to prevent unexpected exception --- doric-iOS/Pod/Classes/DoricContext.h | 2 + doric-iOS/Pod/Classes/DoricContext.m | 16 ++++++- .../Pod/Classes/Plugin/DoricAnimatePlugin.m | 6 ++- .../Classes/Plugin/DoricCoordinatorPlugin.m | 6 ++- .../Pod/Classes/Plugin/DoricModalPlugin.m | 28 +++++++---- .../Pod/Classes/Plugin/DoricNavBarPlugin.m | 48 ++++++++++++------- .../Pod/Classes/Plugin/DoricNavigatorPlugin.m | 16 ++++--- .../Pod/Classes/Plugin/DoricNotchPlugin.m | 24 +++++----- .../Pod/Classes/Plugin/DoricPopoverPlugin.m | 12 +++-- .../Pod/Classes/Plugin/DoricShaderPlugin.m | 10 ++-- .../Pod/Classes/Plugin/DoricStatusBarPlugin.m | 22 +++++---- 11 files changed, 125 insertions(+), 65 deletions(-) diff --git a/doric-iOS/Pod/Classes/DoricContext.h b/doric-iOS/Pod/Classes/DoricContext.h index 01402067..8d05d356 100644 --- a/doric-iOS/Pod/Classes/DoricContext.h +++ b/doric-iOS/Pod/Classes/DoricContext.h @@ -64,6 +64,8 @@ NS_ASSUME_NONNULL_BEGIN - (void)onHidden; - (DoricViewNode *)targetViewNode:(NSString *)viewId; + +- (void)dispatchToMainQueue:(_Nonnull dispatch_block_t)block; @end NS_ASSUME_NONNULL_END diff --git a/doric-iOS/Pod/Classes/DoricContext.m b/doric-iOS/Pod/Classes/DoricContext.m index 5961283b..74134132 100644 --- a/doric-iOS/Pod/Classes/DoricContext.m +++ b/doric-iOS/Pod/Classes/DoricContext.m @@ -26,6 +26,7 @@ #import "DoricConstant.h" #import "DoricExtensions.h" #import "DoricNativeDriver.h" +#import "DoricUtil.h" @implementation DoricContext @@ -115,10 +116,23 @@ - (void)onShow { - (void)onHidden { [self callEntity:DORIC_ENTITY_HIDDEN withArgumentsArray:@[]]; } + - (UIViewController *)vc { - if(!_vc) { + if (!_vc) { return [UIApplication sharedApplication].keyWindow.rootViewController; } return _vc; } + + +- (void)dispatchToMainQueue:(_Nonnull dispatch_block_t)block { + dispatch_async(dispatch_get_main_queue(), ^{ + @try { + block(); + } @catch (NSException *exception) { + DoricLog(@"dispatchToMainQueue Error:%@", exception.reason); + [self.driver.registry onException:exception inContext:self]; + } + }); +} @end diff --git a/doric-iOS/Pod/Classes/Plugin/DoricAnimatePlugin.m b/doric-iOS/Pod/Classes/Plugin/DoricAnimatePlugin.m index c180beb9..2c9ad353 100644 --- a/doric-iOS/Pod/Classes/Plugin/DoricAnimatePlugin.m +++ b/doric-iOS/Pod/Classes/Plugin/DoricAnimatePlugin.m @@ -28,7 +28,9 @@ - (void)submit:(NSDictionary *)args withPromise:(DoricPromise *)promise { - (void)animateRender:(NSDictionary *)args withPromise:(DoricPromise *)promise { NSNumber *duration = args[@"duration"]; - dispatch_async(dispatch_get_main_queue(), ^{ + __weak typeof(self) _self = self; + [self.doricContext dispatchToMainQueue:^{ + __strong typeof(_self) self = _self; NSString *viewId = args[@"id"]; [UIView animateWithDuration:[duration floatValue] / 1000 animations:^{ @@ -45,6 +47,6 @@ - (void)animateRender:(NSDictionary *)args withPromise:(DoricPromise *)promise { completion:^(BOOL finished) { [promise resolve:nil]; }]; - }); + }]; } @end diff --git a/doric-iOS/Pod/Classes/Plugin/DoricCoordinatorPlugin.m b/doric-iOS/Pod/Classes/Plugin/DoricCoordinatorPlugin.m index ece679c5..36c82c9f 100644 --- a/doric-iOS/Pod/Classes/Plugin/DoricCoordinatorPlugin.m +++ b/doric-iOS/Pod/Classes/Plugin/DoricCoordinatorPlugin.m @@ -26,7 +26,9 @@ @implementation DoricCoordinatorPlugin - (void)verticalScrolling:(NSDictionary *)params withPromise:(DoricPromise *)promise { - dispatch_async(dispatch_get_main_queue(), ^{ + __weak typeof(self) _self = self; + [self.doricContext dispatchToMainQueue:^{ + __strong typeof(_self) self = _self; NSArray *scrollableIds = params[@"scrollable"]; DoricViewNode *scrollNode = nil; for (NSString *value in scrollableIds) { @@ -103,7 +105,7 @@ - (void)verticalScrolling:(NSDictionary *)params withPromise:(DoricPromise *)pro } else { [promise reject:@"Scroller type error"]; } - }); + }]; } - (void)setValue:(DoricViewNode *)viewNode isNavBar:(BOOL)isNavBar name:(NSString *)name value:(id)value { diff --git a/doric-iOS/Pod/Classes/Plugin/DoricModalPlugin.m b/doric-iOS/Pod/Classes/Plugin/DoricModalPlugin.m index 0981ac1c..222f7403 100644 --- a/doric-iOS/Pod/Classes/Plugin/DoricModalPlugin.m +++ b/doric-iOS/Pod/Classes/Plugin/DoricModalPlugin.m @@ -27,7 +27,9 @@ @implementation DoricModalPlugin - (void)toast:(NSDictionary *)dic withPromise:(DoricPromise *)promise { - dispatch_async(dispatch_get_main_queue(), ^{ + __weak typeof(self) _self = self; + [self.doricContext dispatchToMainQueue:^{ + __strong typeof(_self) self = _self; __block DoricGravity gravity = DoricGravityBottom; [dic[@"gravity"] also:^(NSNumber *it) { gravity = (DoricGravity) [it integerValue]; @@ -37,11 +39,13 @@ - (void)toast:(NSDictionary *)dic withPromise:(DoricPromise *)promise { } else { ShowToast(dic[@"msg"], gravity); } - }); + }]; } - (void)alert:(NSDictionary *)dic withPromise:(DoricPromise *)promise { - dispatch_async(dispatch_get_main_queue(), ^{ + __weak typeof(self) _self = self; + [self.doricContext dispatchToMainQueue:^{ + __strong typeof(_self) self = _self; UIAlertController *alert = [UIAlertController alertControllerWithTitle:dic[@"title"] message:dic[@"msg"] preferredStyle:UIAlertControllerStyleAlert]; @@ -52,11 +56,13 @@ - (void)alert:(NSDictionary *)dic withPromise:(DoricPromise *)promise { }]; [alert addAction:action]; [self.doricContext.vc presentViewController:alert animated:YES completion:nil]; - }); + }]; } - (void)confirm:(NSDictionary *)dic withPromise:(DoricPromise *)promise { - dispatch_async(dispatch_get_main_queue(), ^{ + __weak typeof(self) _self = self; + [self.doricContext dispatchToMainQueue:^{ + __strong typeof(_self) self = _self; UIAlertController *alert = [UIAlertController alertControllerWithTitle:dic[@"title"] message:dic[@"msg"] preferredStyle:UIAlertControllerStyleAlert]; @@ -67,20 +73,22 @@ - (void)confirm:(NSDictionary *)dic withPromise:(DoricPromise *)promise { [promise reject:nil]; }]; [alert addAction:cancelAction]; - + UIAlertAction *okAction = [UIAlertAction actionWithTitle:dic[@"okLabel"] ?: NSLocalizedString(@"Ok", nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) { [promise resolve:nil]; }]; [alert addAction:okAction]; - + [self.doricContext.vc presentViewController:alert animated:YES completion:nil]; - }); + }]; } - (void)prompt:(NSDictionary *)dic withPromise:(DoricPromise *)promise { - dispatch_async(dispatch_get_main_queue(), ^{ + __weak typeof(self) _self = self; + [self.doricContext dispatchToMainQueue:^{ + __strong typeof(_self) self = _self; UIAlertController *alert = [UIAlertController alertControllerWithTitle:dic[@"title"] message:dic[@"msg"] preferredStyle:UIAlertControllerStyleAlert]; @@ -113,6 +121,6 @@ - (void)prompt:(NSDictionary *)dic withPromise:(DoricPromise *)promise { [alert addAction:okAction]; [self.doricContext.vc presentViewController:alert animated:YES completion:nil]; - }); + }]; } @end diff --git a/doric-iOS/Pod/Classes/Plugin/DoricNavBarPlugin.m b/doric-iOS/Pod/Classes/Plugin/DoricNavBarPlugin.m index 12ec3571..471f99d2 100644 --- a/doric-iOS/Pod/Classes/Plugin/DoricNavBarPlugin.m +++ b/doric-iOS/Pod/Classes/Plugin/DoricNavBarPlugin.m @@ -30,9 +30,11 @@ @implementation DoricNavBarPlugin - (void)isHidden:(NSDictionary *)param withPromise:(DoricPromise *)promise { if (self.doricContext.navBar) { - dispatch_async(dispatch_get_main_queue(), ^{ + __weak typeof(self) _self = self; + [self.doricContext dispatchToMainQueue:^{ + __strong typeof(_self) self = _self; [promise resolve:@([self.doricContext.navBar doric_navBar_isHidden])]; - }); + }]; } else { [promise reject:@"Not implement NavBar"]; } @@ -40,10 +42,12 @@ - (void)isHidden:(NSDictionary *)param withPromise:(DoricPromise *)promise { - (void)setHidden:(NSDictionary *)param withPromise:(DoricPromise *)promise { if (self.doricContext.navBar) { - dispatch_async(dispatch_get_main_queue(), ^{ + __weak typeof(self) _self = self; + [self.doricContext dispatchToMainQueue:^{ + __strong typeof(_self) self = _self; [self.doricContext.navBar doric_navBar_setHidden:[param[@"hidden"] boolValue]]; [promise resolve:nil]; - }); + }]; } else { [promise reject:@"Not implement NavBar"]; } @@ -51,10 +55,12 @@ - (void)setHidden:(NSDictionary *)param withPromise:(DoricPromise *)promise { - (void)setTitle:(NSDictionary *)param withPromise:(DoricPromise *)promise { if (self.doricContext.navBar) { - dispatch_async(dispatch_get_main_queue(), ^{ + __weak typeof(self) _self = self; + [self.doricContext dispatchToMainQueue:^{ + __strong typeof(_self) self = _self; [self.doricContext.navBar doric_navBar_setTitle:param[@"title"]]; [promise resolve:nil]; - }); + }]; } else { [promise reject:@"Not implement NavBar"]; } @@ -62,11 +68,13 @@ - (void)setTitle:(NSDictionary *)param withPromise:(DoricPromise *)promise { - (void)setBgColor:(NSDictionary *)param withPromise:(DoricPromise *)promise { if (self.doricContext.navBar) { - dispatch_async(dispatch_get_main_queue(), ^{ + __weak typeof(self) _self = self; + [self.doricContext dispatchToMainQueue:^{ + __strong typeof(_self) self = _self; UIColor *color = DoricColor(param[@"color"]); [self.doricContext.navBar doric_navBar_setBackgroundColor:color]; [promise resolve:nil]; - }); + }]; } else { [promise reject:@"Not implement NavBar"]; } @@ -74,7 +82,9 @@ - (void)setBgColor:(NSDictionary *)param withPromise:(DoricPromise *)promise { - (void)setLeft:(NSDictionary *)params withPromise:(DoricPromise *)promise { if (self.doricContext.navBar) { - dispatch_async(dispatch_get_main_queue(), ^{ + __weak typeof(self) _self = self; + [self.doricContext dispatchToMainQueue:^{ + __strong typeof(_self) self = _self; NSString *viewId = params[@"id"]; NSString *type = params[@"type"]; DoricViewNode *viewNode = [self.doricContext targetViewNode:viewId]; @@ -82,7 +92,7 @@ - (void)setLeft:(NSDictionary *)params withPromise:(DoricPromise *)promise { viewNode = [[DoricViewNode create:self.doricContext withType:type] also:^(DoricViewNode *it) { it.viewId = viewId; [it initWithSuperNode:nil]; - + NSMutableDictionary *map = self.doricContext.headNodes[TYPE_LEFT]; if (map != nil) { self.doricContext.headNodes[TYPE_LEFT][viewId] = it; @@ -96,7 +106,7 @@ - (void)setLeft:(NSDictionary *)params withPromise:(DoricPromise *)promise { [viewNode blend:params[@"props"]]; [self.doricContext.navBar doric_navBar_setLeft:viewNode.view]; [promise resolve:nil]; - }); + }]; } else { [promise reject:@"Not implement NavBar"]; } @@ -104,7 +114,9 @@ - (void)setLeft:(NSDictionary *)params withPromise:(DoricPromise *)promise { - (void)setRight:(NSDictionary *)params withPromise:(DoricPromise *)promise { if (self.doricContext.navBar) { - dispatch_async(dispatch_get_main_queue(), ^{ + __weak typeof(self) _self = self; + [self.doricContext dispatchToMainQueue:^{ + __strong typeof(_self) self = _self; NSString *viewId = params[@"id"]; NSString *type = params[@"type"]; DoricViewNode *viewNode = [self.doricContext targetViewNode:viewId]; @@ -112,7 +124,7 @@ - (void)setRight:(NSDictionary *)params withPromise:(DoricPromise *)promise { viewNode = [[DoricViewNode create:self.doricContext withType:type] also:^(DoricViewNode *it) { it.viewId = viewId; [it initWithSuperNode:nil]; - + NSMutableDictionary *map = self.doricContext.headNodes[TYPE_RIGHT]; if (map != nil) { self.doricContext.headNodes[TYPE_RIGHT][viewId] = it; @@ -126,7 +138,7 @@ - (void)setRight:(NSDictionary *)params withPromise:(DoricPromise *)promise { [viewNode blend:params[@"props"]]; [self.doricContext.navBar doric_navBar_setRight:viewNode.view]; [promise resolve:nil]; - }); + }]; } else { [promise reject:@"Not implement NavBar"]; } @@ -134,7 +146,9 @@ - (void)setRight:(NSDictionary *)params withPromise:(DoricPromise *)promise { - (void)setCenter:(NSDictionary *)params withPromise:(DoricPromise *)promise { if (self.doricContext.navBar) { - dispatch_async(dispatch_get_main_queue(), ^{ + __weak typeof(self) _self = self; + [self.doricContext dispatchToMainQueue:^{ + __strong typeof(_self) self = _self; NSString *viewId = params[@"id"]; NSString *type = params[@"type"]; DoricViewNode *viewNode = [self.doricContext targetViewNode:viewId]; @@ -142,7 +156,7 @@ - (void)setCenter:(NSDictionary *)params withPromise:(DoricPromise *)promise { viewNode = [[DoricViewNode create:self.doricContext withType:type] also:^(DoricViewNode *it) { it.viewId = viewId; [it initWithSuperNode:nil]; - + NSMutableDictionary *map = self.doricContext.headNodes[TYPE_CENTER]; if (map != nil) { self.doricContext.headNodes[TYPE_CENTER][viewId] = it; @@ -156,7 +170,7 @@ - (void)setCenter:(NSDictionary *)params withPromise:(DoricPromise *)promise { [viewNode blend:params[@"props"]]; [self.doricContext.navBar doric_navBar_setCenter:viewNode.view]; [promise resolve:nil]; - }); + }]; } else { [promise reject:@"Not implement NavBar"]; } diff --git a/doric-iOS/Pod/Classes/Plugin/DoricNavigatorPlugin.m b/doric-iOS/Pod/Classes/Plugin/DoricNavigatorPlugin.m index 1497bc80..4ce7ff9c 100644 --- a/doric-iOS/Pod/Classes/Plugin/DoricNavigatorPlugin.m +++ b/doric-iOS/Pod/Classes/Plugin/DoricNavigatorPlugin.m @@ -22,7 +22,9 @@ @implementation DoricNavigatorPlugin - (void)push:(NSDictionary *)params { - dispatch_async(dispatch_get_main_queue(), ^{ + __weak typeof(self) _self = self; + [self.doricContext dispatchToMainQueue:^{ + __strong typeof(_self) self = _self; BOOL animated = YES; NSString *source = params[@"source"]; NSString *alias = source; @@ -37,21 +39,23 @@ - (void)push:(NSDictionary *)params { } } [self.doricContext.navigator doric_navigator_push:source alias:alias animated:animated extra:config[@"extra"]]; - }); + }]; } - (void)pop:(NSDictionary *)params { - dispatch_async(dispatch_get_main_queue(), ^{ + __weak typeof(self) _self = self; + [self.doricContext dispatchToMainQueue:^{ + __strong typeof(_self) self = _self; BOOL animated = YES; if (params[@"animated"]) { animated = [params[@"animated"] boolValue]; } [self.doricContext.navigator doric_navigator_pop:animated]; - }); + }]; } - (void)openUrl:(NSString *)urlString withPromise:(DoricPromise *)promise { - dispatch_async(dispatch_get_main_queue(), ^{ + [self.doricContext dispatchToMainQueue:^{ NSURL *url = [NSURL URLWithString:urlString]; [UIApplication.sharedApplication openURL:url options:@{} completionHandler:^(BOOL success) { if (success) { @@ -60,6 +64,6 @@ - (void)openUrl:(NSString *)urlString withPromise:(DoricPromise *)promise { [promise reject:@"Cannot open"]; } }]; - }); + }]; } @end diff --git a/doric-iOS/Pod/Classes/Plugin/DoricNotchPlugin.m b/doric-iOS/Pod/Classes/Plugin/DoricNotchPlugin.m index 6f16b51e..ba935427 100644 --- a/doric-iOS/Pod/Classes/Plugin/DoricNotchPlugin.m +++ b/doric-iOS/Pod/Classes/Plugin/DoricNotchPlugin.m @@ -30,7 +30,9 @@ - (instancetype)initWithContext:(DoricContext *)doricContext { } - (void)inset:(NSDictionary *)argument withPromise:(DoricPromise *)promise { - dispatch_async(dispatch_get_main_queue(), ^{ + __weak typeof(self) _self = self; + [self.doricContext dispatchToMainQueue:^{ + __strong typeof(_self) self = _self; if (@available(iOS 11.0, *)) { UIView *superView; if (self.doricContext.vc) { @@ -38,25 +40,25 @@ - (void)inset:(NSDictionary *)argument withPromise:(DoricPromise *)promise { } else { superView = [UIApplication sharedApplication].windows.lastObject; } - + CGFloat top = superView.safeAreaInsets.top; CGFloat left = superView.safeAreaInsets.left; CGFloat bottom = superView.safeAreaInsets.bottom; CGFloat right = superView.safeAreaInsets.right; [promise resolve:@{ - @"top": @(top), - @"left": @(left), - @"bottom": @(bottom), - @"right": @(right), + @"top": @(top), + @"left": @(left), + @"bottom": @(bottom), + @"right": @(right), }]; } else { [promise resolve:@{ - @"top": @(0), - @"left": @(0), - @"bottom": @(0), - @"right": @(0), + @"top": @(0), + @"left": @(0), + @"bottom": @(0), + @"right": @(0), }]; } - }); + }]; } @end diff --git a/doric-iOS/Pod/Classes/Plugin/DoricPopoverPlugin.m b/doric-iOS/Pod/Classes/Plugin/DoricPopoverPlugin.m index fa8f02e8..8a8b1a6a 100644 --- a/doric-iOS/Pod/Classes/Plugin/DoricPopoverPlugin.m +++ b/doric-iOS/Pod/Classes/Plugin/DoricPopoverPlugin.m @@ -14,7 +14,9 @@ @implementation DoricPopoverPlugin static NSString *TYPE = @"popover"; - (void)show:(NSDictionary *)params withPromise:(DoricPromise *)promise { - dispatch_async(dispatch_get_main_queue(), ^{ + __weak typeof(self) _self = self; + [self.doricContext dispatchToMainQueue:^{ + __strong typeof(_self) self = _self; UIView *superView = self.doricContext.vc.view; if (!self.fullScreenView) { self.fullScreenView = [[UIView new] also:^(UIView *it) { @@ -52,12 +54,14 @@ - (void)show:(NSDictionary *)params withPromise:(DoricPromise *)promise { [viewNode blend:params[@"props"]]; [self.fullScreenView.doricLayout apply]; [promise resolve:nil]; - }); + }]; } - (void)dismiss:(NSDictionary *)params withPromise:(DoricPromise *)promise { NSString *viewId = params[@"id"]; - dispatch_async(dispatch_get_main_queue(), ^{ + __weak typeof(self) _self = self; + [self.doricContext dispatchToMainQueue:^{ + __strong typeof(_self) self = _self; if (viewId) { DoricViewNode *viewNode = [self.doricContext targetViewNode:viewId]; [self dismissViewNode:viewNode]; @@ -65,7 +69,7 @@ - (void)dismiss:(NSDictionary *)params withPromise:(DoricPromise *)promise { [self dismissPopover]; } [promise resolve:nil]; - }); + }]; } - (void)dismissViewNode:(DoricViewNode *)node { diff --git a/doric-iOS/Pod/Classes/Plugin/DoricShaderPlugin.m b/doric-iOS/Pod/Classes/Plugin/DoricShaderPlugin.m index 0d5f926a..ffa0ca8f 100644 --- a/doric-iOS/Pod/Classes/Plugin/DoricShaderPlugin.m +++ b/doric-iOS/Pod/Classes/Plugin/DoricShaderPlugin.m @@ -33,7 +33,7 @@ - (void)render:(NSDictionary *)argument withPromise:(DoricPromise *)promise { return; } __weak typeof(self) _self = self; - dispatch_async(dispatch_get_main_queue(), ^{ + [self.doricContext dispatchToMainQueue:^{ __strong typeof(_self) self = _self; if (self.doricContext == nil) { return; @@ -50,11 +50,13 @@ - (void)render:(NSDictionary *)argument withPromise:(DoricPromise *)promise { [viewNode requestLayout]; } [promise resolve:nil]; - }); + }]; } - (void)command:(NSDictionary *)argument withPromise:(DoricPromise *)promise { - dispatch_async(dispatch_get_main_queue(), ^{ + __weak typeof(self) _self = self; + [self.doricContext dispatchToMainQueue:^{ + __strong typeof(_self) self = _self; if (self.doricContext == nil) { return; } @@ -76,7 +78,7 @@ - (void)command:(NSDictionary *)argument withPromise:(DoricPromise *)promise { } else { [self findClass:[viewNode class] target:viewNode method:name promise:promise argument:args]; } - }); + }]; } - (id)createParamWithMethodName:(NSString *)method promise:(DoricPromise *)promise argument:(id)argument { diff --git a/doric-iOS/Pod/Classes/Plugin/DoricStatusBarPlugin.m b/doric-iOS/Pod/Classes/Plugin/DoricStatusBarPlugin.m index b8bd2441..0a2f5f8c 100644 --- a/doric-iOS/Pod/Classes/Plugin/DoricStatusBarPlugin.m +++ b/doric-iOS/Pod/Classes/Plugin/DoricStatusBarPlugin.m @@ -26,36 +26,42 @@ @implementation DoricStatusBarPlugin - (void)setHidden:(NSDictionary *)param withPromise:(DoricPromise *)promise { - dispatch_async(dispatch_get_main_queue(), ^{ + __weak typeof(self) _self = self; + [self.doricContext dispatchToMainQueue:^{ + __strong typeof(_self) self = _self; if (self.doricContext.navBar) { if ([self.doricContext.navBar isKindOfClass:DoricViewController.class]) { - DoricViewController * target = ((DoricViewController *)self.doricContext.navBar); + DoricViewController *target = ((DoricViewController *) self.doricContext.navBar); target.statusBarHidden = [param[@"hidden"] boolValue]; [target setNeedsStatusBarAppearanceUpdate]; } } - }); + }]; } - (void)setMode:(NSDictionary *)param withPromise:(DoricPromise *)promise { - dispatch_async(dispatch_get_main_queue(), ^{ + __weak typeof(self) _self = self; + [self.doricContext dispatchToMainQueue:^{ + __strong typeof(_self) self = _self; if (self.doricContext.navBar) { if ([self.doricContext.navBar isKindOfClass:DoricViewController.class]) { - DoricViewController * target = ((DoricViewController *)self.doricContext.navBar); + DoricViewController *target = ((DoricViewController *) self.doricContext.navBar); target.statusBarMode = [param[@"mode"] intValue]; [target setNeedsStatusBarAppearanceUpdate]; } } - }); + }]; } - (void)setColor:(NSDictionary *)param withPromise:(DoricPromise *)promise { - dispatch_async(dispatch_get_main_queue(), ^{ + __weak typeof(self) _self = self; + [self.doricContext dispatchToMainQueue:^{ + __strong typeof(_self) self = _self; if (self.doricContext.navBar) { UIColor *color = DoricColor(param[@"color"]); [self.doricContext.navBar doric_navBar_setBackgroundColor:color]; } - }); + }]; } @end