从 iOS 中的 C 函数内更新 UI 线程
我正在使用 C 程序来尝试在我的 iOS 应用程序中使用它,并尽可能少地进行修改。 C 程序对一组输入执行大量计算。
在 iOS 方面,我使用以下代码创建一个线程来运行计算,并且还有一种机制来报告完成时的情况(目前,它在完成时更新 UILabel os“testLabel”)
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
char *testChar = startProgram( nx, ny, nz ); // this is where I call the C program
dispatch_async(dispatch_get_main_queue(), ^{
NSString *tempString = [[NSString alloc]initWithCString: testChar ];
testLabel.text = tempString;
[tempString release];
});
});
:工作后,我得到结果,并且我的 UI 保持响应。
但是,我希望在计算进行时从 C 例程通信回 UI,以便获取状态以及增量地传回一些数据。
所以我的 C 程序会是这样的:
char* startProgram( int nx, int ny, int nz )
{
setupEverything(); // this is just pseudo code for clarity
for( int i = 0; i < nz; i++ )
{
doMajorCalculations();
reportBackToUI( someResults ); // This is what I would LIKE to do
}
}
我在这里看到一个关于传递“self”的线程,但我不认为上面传递的“self”将是我的类“self”。另外,我尝试了一下,在 C 端出现错误,说它无法识别“id”类型。我将“id”的类型更改为类名,它告诉我参数错误。
关于实现这一点的最佳方法有什么想法吗?
感谢您的帮助。
I am working with a C program to try and use it in my iOS application with as little modification as possible. The C program performs a lot of calculations on a set of inputs.
On the iOS side, I am using the following code to create a thread to run the calculations, and also to have a mechanism to report when it is complete (currently, it updates a UILabel os "testLabel" when complete):
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
char *testChar = startProgram( nx, ny, nz ); // this is where I call the C program
dispatch_async(dispatch_get_main_queue(), ^{
NSString *tempString = [[NSString alloc]initWithCString: testChar ];
testLabel.text = tempString;
[tempString release];
});
});
This seems to work, I get my results, and my UI stays responsive.
However, I am wanting to communicate from the C routine back to the UI while the calculations are going on in order to get status as well as to pass some data back incrementally.
So my C program would be something like this:
char* startProgram( int nx, int ny, int nz )
{
setupEverything(); // this is just pseudo code for clarity
for( int i = 0; i < nz; i++ )
{
doMajorCalculations();
reportBackToUI( someResults ); // This is what I would LIKE to do
}
}
I saw a thread on here about passing "self", but I don't think the "self" if passed above would be my class "self". In addition, I tried that and got an error on the C-side of things, saying that it did not recognize the type "id". I changed the type of "id" to the class name, and it told me the parameter was wrong.
Any ideas on the best way to implement this?
Thank you for your help.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
声明一个全局 c void*
并在类初始值设定项中为其分配 Objective-C 类对象
现在,每当您需要从 C 函数调用某些内容时,请执行以下操作,
这将调用相应的 Objective-C 函数,您可以调用您的主 UI 线程在那个函数中。
您可以创建一个单例类,并在初始化时将其分配给 void 指针,然后在 C 函数中执行所需的操作。
declare a global c void*
And assign it the objective-c class object in your class initializer
Now whenever you need to invoke something from C function do the following,
This will call the corresponding objective-C function and you can invoke ur main UI thread in that function.
You could create a singleton class and assign it to the void pointer in its initialization and then do the needful in ur C function.
也许您想要的是有一个块作为回调,用于向调用者报告部分结果。像这样的东西:
然后客户端可以使用类似的东西调用
startProgram
:这样你的代码将不依赖于客户端做什么或如何使用进度回调。这也是很好的依赖注入。
如果无法使用块(模型代码可能需要纯 C 才能在其他平台上工作?),那么您可以将块切换为函数指针。
Maybe what you want is to have a block as a callback for reporting back partial results to the caller. Something like this:
Then the client could call
startProgram
using something like:This way your code will have no dependency on what or how the client do and uses the progress callback for. Also it is nice dependency injection.
If using blocks is not possible (model code might need to be pure C to work on other platforms?) then you can switch the block for a function pointer.