【发布时间】:2022-12-12 07:07:11
【问题描述】:
好的,这有点复杂。我无法链接我的所有代码,因为它很大,但我会尽力在其中提供一些有代表性的伪代码。
我有一个 ios React Native 项目,在 xcode 中,我在我的项目中嵌入了一个自定义目标 C 框架。为了访问目标 C 框架,我创建了一个充当包装器/桥接器的本机模块。
到目前为止,这一切都很好——基本上我的用户点击了一个按钮,它通过一个本机模块触发了 objective c 框架,objective c 框架需要大约 30 秒到一分钟来完成处理用户选择的数据,然后吐出已处理文件的 uri。
我遇到的问题是我的用户对我的应用程序是否被冻结感到困惑。碰巧我的框架的主要功能使用 for 循环,所以我决定向框架的主类添加两个属性并添加一个返回属性的函数,以便我们可以看到进度。它看起来像这样:
@implementation MyFramework {
int currentBlock;
int allBlocks;
}
- (NSArray<NSString*>*)processFile:(NSString *)file
{
int totalBlocks = examineFile(file);
for( int iBlock= 0; iBlock<totalBlocks; iBlock++) {
currentBlock = iBlock;
//other code that actually does stuff to the file goes here
}
//code that stitches the blocks together and generates files goes here
NSArray* files = @[filePath1, filePath2, filepath3];
return files;
}
- (NSArray<NSString*>*)getProgress:(NSString *)msg
{
int* pCurrentBlock = ¤tBlock;
int* pAllBlocks = &allBlocks;
NSString* currentBlockString = [NSString stringWithFormat:@"%d", *pCurrentBlock];
NSString* allBlocksString = [NSString stringWithFormat:@"%d", *pAllBlocks];
NSArray* progressArray = @[currentBlockString, allBlocksString];
return progressArray;
}
回到 Javascript 中,我为上面的代码调用了一个 Native Module wrapper。因此,当用户单击一个按钮时,我会触发一个名为 getFiles() 的本机模块方法,该方法又会调用上面 Objective C 代码中的 processFile() 方法。
现在,当 processFile() 方法运行时,我每 2 秒同时启动一个 setInterval() 调用第二个名为 status() 的本机模块方法,该方法调用上面显示的 getProgress() 函数。我遇到的大问题是 getProgress() 在 processFile() 运行时不会返回结果。相反,它会等到 processFile() 方法完成,然后一次返回大约 20 个结果。
所以不要像这样获取更新:
['1','37']
['2','37']
['3','37']
['4','37']
['5','37']
最后我得到了这样的东西
['36','37']
['36','37']
['36','37']
['36','37']
['36','37']
这是我的本机模块代码
const MyFramework *myLocalFramework = [[MyFramework alloc]init];
RCT_EXPORT_MODULE();
RCT_EXPORT_METHOD(getFiles:(NSString *)path
resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
{
NSString *modelFilePath = [[NSBundle mainBundle] pathForResource:@"converted_model_float16" ofType:@"tflite"];
NSArray * files = [myLocalFramework localFile:path tfModel:modelFilePath];
if (files) {
resolve(files);
} else {
reject(@"event_failure", @"no event id returned", nil);
}
}
RCT_EXPORT_METHOD(status:(NSString *)path
resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
{
NSString* hi = @"hi";
NSArray* percentages = [myLocalFramework getProgress:hi];
if (percentages) {
resolve(percentages);
} else {
reject(@"event_failure", @"no event id returned", nil);
}
}
因此,综上所述,如果有人对我如何让本机模块运行 status() 方法而不等待 getFiles() 首先完成有任何想法,我会喜欢你的意见!
【问题讨论】:
-
可以选择事件侦听器,而不是添加用于获取进度状态的本机模块。