前阵子,我在这里问过类似的问题: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
因此,我认为无论所有软件包如何都需要使用requiresMainQueueSetup
?但是,我很难把握何时需要将其设置为YES
或NO
。这些模块都不是ui组件,谷歌登录一个,但是打开了safari视图控制器来执行oAuth,这是否意味着需要在此处将值设置为YES
?
每当我使用任何本机化的解析器/拒绝器桥接方法时,都需要使用dispatch_get_main_queue
吗?
答案 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
实现,它告诉您确切的原因-一个模块正在覆盖init
或constantsToExport
方法,但未指定是否希望在主线程上执行该方法。到现在为止,覆盖init
或constantsToExport
的模块默认情况下是在主线程上初始化的,假设它们可能需要访问UI元素或UIKit
。在将来的RN版本中,这种情况将会改变-仅当您明确声明时,才会在主线程上调用这些方法。
您在init
或constantsToExport
中做的工作似乎并不需要主线程,但此刻似乎您正在覆盖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];
});