ios - react-native iOS原生模块:异步激活网络指示器的调用方法
问题描述
我正在编写一个本机模块,该模块从我无权访问的封闭源代码框架二进制文件中调用函数。它会阻止网络调用并激活网络指示器。我希望能够在后台异步运行它,它有点开箱即用,但是当我这样做时,我得到这个警告/错误并且调用有点停顿:
Main Thread Checker: UI API called on a background thread: -[UIApplication setNetworkActivityIndicatorVisible:]
如果我在我的 RN 模块中使用以下代码将它放在主队列中,调用会阻塞所有内容,直到它们完成。
- (dispatch_queue_t)methodQueue
{
return dispatch_get_main_queue();
}
下面是一个暴露给 JS 的方法的例子:
RCT_REMAP_METHOD(createSession,
userIDtoken:(NSString *)userIDtoken
createSessionWithResolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
{
Boolean connected = [_networkController startSession:userIDtoken isTest:true];
NSString *success = @"session created";
if (connected){
resolve(success);
} else {
NSError *error = [NSError errorWithDomain:@"ConnectionError" code:1 userInfo:nil];
reject(@"session_creation_failed", @"Cannot create sessions", error);
}
}
_networkController startSession
应该在后台运行而不会抛出警告/错误并且不会阻塞主线程。有没有办法做到这一点?
解决方案
您不能UIKit
在后台线程上进行 API 调用,因为它不是线程安全的。
您可以删除 RN 模块methodQueue
设置,以便您的模块方法将在后台线程上再次调用,并且不会阻塞主线程。每当您需要调用[UIApplication setNetworkActivityIndicatorVisible:]
(或任何其他需要主队列的方法)时,都可以将其分派到主线程,例如:
dispatch_async(dispatch_get_main_queue(), ^{
[UIApplication.sharedApplication setNetworkActivityIndicatorVisible:YES];
});
如果您只需要在设置活动指示器后解决承诺,您还可以在更改活动指示器可见性后将您的调用以解决/拒绝放在同一块内。
推荐阅读
- android - BuildConfig 变量。错误:找不到符号
- javascript - 跨电子书页面共享数据
- c# - 如何更改这些代码以更快地执行
- router - 思科路由器获得 CPU 使用百分比
- android - 如何为 Simplee Drawee Android 的所有角落设置半径
- javascript - 在 Rails 中使用 ajax 返回值
- javascript - 有没有更好的方法来根据 JS 的存在来隐藏/显示元素?
- wxpython - 尝试 TreeCtrl 小部件,退出时出现运行时错误
- angular - 我们可以使用单个 ion-textarea 发表评论并同时回复评论吗
- angular - 使用 ngrx 效果或组件提交数据