2017-09-13 69 views
0

我有陣營本土原生module,打開Safari瀏覽器視圖控制器:如何打「集合被列舉時發生了變異」錯誤?

RCTSFSafariViewController.m:

#import "RCTSFSafariViewController.h" 

@implementation RCTSFSafariViewController 

@synthesize bridge = _bridge; 

RCT_EXPORT_MODULE(); 

- (void)safariViewControllerDidFinish:(SFSafariViewController *)controller { 
    [self.bridge.eventDispatcher sendAppEventWithName:@"SFSafariViewControllerDismissed" body:nil]; 
} 

RCT_EXPORT_METHOD(openURL:(NSString *)urlString params:(NSDictionary *)params) { 
    NSURL *url = [[NSURL alloc] initWithString:urlString]; 

    SFSafariViewController *safariViewController = [[SFSafariViewController alloc] initWithURL:url]; 
    UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:safariViewController]; 

    [navigationController setNavigationBarHidden:YES animated:NO]; 
    safariViewController.delegate = self; 

    if ([params objectForKey:@"tintColor"]) { 
    UIColor *tintColor = [RCTConvert UIColor:params[@"tintColor"]]; 

    if([safariViewController respondsToSelector:@selector(setPreferredControlTintColor:)]) { 
     safariViewController.preferredControlTintColor = tintColor; 
    } else { 
     safariViewController.view.tintColor = tintColor; 
    } 
    } 

    dispatch_sync(dispatch_get_main_queue(), ^{ 
    [rootViewController.rootViewController.presentedViewController presentViewController:navigationController animated:YES completion:^{ 
     [self.bridge.eventDispatcher sendDeviceEventWithName:@"SFSafariViewControllerDidLoad" body:nil]; 
    }]; 
    }); 
} 

RCT_EXPORT_METHOD(close) { 
    dispatch_async(dispatch_get_main_queue(), ^{ 
    UIViewController *rootViewController = [[[UIApplication sharedApplication] delegate] window].rootViewController; 
    [rootViewController dismissViewControllerAnimated:YES completion:nil]; 
    }); 
} 

@end 

RCTSFSafariViewController.h:

#import <React/RCTBridgeModule.h> 
#import <React/RCTConvert.h> 
#import <React/RCTEventDispatcher.h> 
#import <UIKit/UIKit.h> 

@import SafariServices; 

@interface RCTSFSafariViewController : NSObject <RCTBridgeModule, SFSafariViewControllerDelegate> 
@end 

它運作良好,在模擬器和我的iPhone ,但很多用戶都面臨這樣的崩潰(根據Crashlytics):

Collection <__NSArrayM: 0x14e3bd20> was mutated while being enumerated.' was thrown while invoking openURL on target SFSafariViewController with params ("https://example.com", { }) 

問題是在此代碼中沒有數組或枚舉結構。我有這個想法,這可能是由dispatch_async引起的,因爲當我刪除它時,應用程序停止崩潰,但在調用SVC後工作速度慢得多。

我在做什麼錯?

回答

0

我認爲這是在非主隊列上調用的。如果它位於主隊列中,則dispatch_sync應該死鎖。與主隊列中的大多數UIKit對象進行交互是不安全的。這可能包括SFSafariViewController(除非你有明確的文件說它是安全的,那麼它不是)。

通話dispatch_sync通常是危險的(不管它會導致死鎖),在這種情況下是不必要的。你可以在這裏使用dispatch_async

您應該將整個方法移至調用主隊列的dispatch_async

+0

我使用dispatch_async和dispatch_sync是我絕望的實驗。但最後一段似乎是可能的解決方案。我會試試看。無論如何,非常感謝您的回答。 – devtwo

+0

不知何故,當調用SFSafariViewController時,將整個方法封裝到'dispatch_async'會導致死鎖:( – devtwo

+0

包裝整個方法並刪除'dispatch_sync',或者離開'dispatch_sync'?如果不刪除'dispatch_sync'調用,完全死鎖(這將是死鎖的典型例子) –

相關問題