通过示例了解何时使用dispatch_get_main_queue和requireMainQueueSetup

时间:2018-06-19 13:40:20

标签: ios objective-c react-native

前阵子,我在这里问过类似的问题:Difference requiresMainQueueSetup and dispatch_get_main_queue?

我今天回到它,意识到我还没有完全掌握它。当我们为iOS编写React本机模块时,在iOS端需要dispatch_get_main_queue,而react-native需要requiresMainQueueSetup

如何使用这些软件包和用例中的哪一种?

asq-react-native-device-软件包,用于导出常量,如bundle id

asq-react-native-sensors-允许从设备陀螺仪和其他传感器订阅和接收数据的软件包

asq-react-native-google-sign-in-软件包tat公开了Google登录sdk

对于所有这些,我都会在开发者控制台中收到警告,即 enter image description here

因此,我认为无论所有软件包如何都需要使用requiresMainQueueSetup?但是,我很难把握何时需要将其设置为YESNO。这些模块都不是ui组件,谷歌登录一个,但是打开了safari视图控制器来执行oAuth,这是否意味着需要在此处将值设置为YES

每当我使用任何本机化的解析器/拒绝器桥接方法时,都需要使用dispatch_get_main_queue吗?

1 个答案:

答案 0 :(得分:12)

虽然这两种方法都与RN与模块交互的方式有关,但它们并不相同。

+ (BOOL)requiresMainQueueSetup

此方法确定您的模块是否在主线程上初始化;换句话说,如果模块的构造函数(init方法)和constantsToExport方法将在主线程上调用。

- (dispatch_queue_t)methodQueue

此方法是一个替代,您可以在调用模块的导出方法(使用RCT_EXPORT_METHOD宏导出)时告诉RN使用哪个调度队列。在此处返回dispatch_get_main_queue()会返回属于主线程的主队列,要求RN在主线程上调用导出的方法,但如果有此要求,则可以使用任何其他自定义分派队列。

主线程执行

如果要简化此操作,则需要在主线程或主调度队列上执行任何涉及UI操作的操作。 即使您的模块不是UI组件,也可以从本机模块执行其他UI操作,例如:提供视图控制器(可以是系统视图控制器或自定义视图控制器)< / p>


如您所见,收到的所有警告都来自缺乏requiresMainQueueSetup实现,它告诉您确切的原因-一个模块正在覆盖initconstantsToExport方法,但未指定是否希望在主线程上执行该方法。到现在为止,覆盖initconstantsToExport的模块默认情况下是在主线程上初始化的,假设它们可能需要访问UI元素或UIKit。在将来的RN版本中,这种情况将会改变-仅当您明确声明时,才会在主线程上调用这些方法。

有问题的包裹

您在initconstantsToExport中做的工作似乎并不需要主线程,但此刻似乎您正在覆盖requiresMainQueueSetup并返回YES。我建议您覆盖它并返回NO,以便您可以测试所有功能是否按预期进行,并确保当RN在将来的RN版本中默认为默认设置时,您不会感到惊讶

请注意,尽管这些不是UI组件,但有时有时在调用导出的方法时确实需要主线程,例如在asq-react-native-google-sign-in中-signIn方法用于显示和关闭视图控制器。在这种情况下,您可以正确覆盖methodQueue并将主队列用于导出的方法。

请注意,也可以通过不重写methodQueue来将方法调用保留在RN后台线程中,并在必要时自己分配给主队列。例如:

dispatch_async(dispatch_get_main_queue(), ^{
    [RCTPresentedViewController() dismissViewControllerAnimated:YES completion:nil];
});