2011-05-10 196 views
2

我正在使用C程序尝试在iOS应用程序中使用它,并尽可能少地进行修改。 C程序对一组输入执行大量计算。从iOS中的C函数更新UI线程

在iOS端,我使用下面的代码来创建一个线程来运行计算,并且还有一个机制来报告它什么时候完成(目前,它完成时会更新一个UILabel操作系统“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]; 

    }); 
}); 

这似乎工作,我得到我的结果,我的用户界面保持响应。

但是,我想从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 
    } 
} 

只见这里一个线程关于通过“自我”,但我不认为“自我”,如果通过以上将是我的班“自”。另外,我尝试了这些,并在事物的C端发生了错误,并说它没有识别“id”类型。我将“id”的类型更改为类名称,并告诉我参数错误。

有关实现此目的的最佳方法的任何想法?

谢谢你的帮助。

回答

2

也许你想要的是有一个块作为回调部分结果回报给调用者。事情是这样的:

char* startProgram(int nx, int ny, int nz, void(^reportBackToUI)(int)) 
{ 
    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 
    } 
} 

然后客户端可以使用类似呼叫startProgram

return startProgram(42, 12, 20, ^(int someResults) { 
      dispatch_async(dispatch_get_main_queue(), ^{ 
       // Update UI in some way. 
      });   
     }); 

这样,你的代码将有什么,或者如何在客户端做并使用进度回调不存在依赖关系。这也是很好的依赖注入。

如果使用块是不可能的(模型代码可能需要纯C才能在其他平台上工作?)然后您可以切换功能指针块。

+0

刚刚注意到块中的dispatch_async,应该可以工作。不抱歉的道歉。 – davydotcom 2011-05-10 19:18:50

+0

@davydotcom:这就是为什么我有dispatch_async(dispatch_get_main_queue(),^ {...'在如何使用回调的例子中,这是在主线程上运行代码的魔力果汁 – PeyloW 2011-05-10 19:32:14

+0

工作!谢谢你的帮帮我。 – 2011-05-11 12:58:01

3

声明一个全局C无效*

void* sipUACObj; 

,并为其分配的Objective-C类对象的类初始化

sipUACObj = self; 

现在只要您需要调用从C函数的东西做以下,

ObjcClass *obj = (ObjcClass*) sipUACObj; 
    [obj someMethod:arg1 Arg2:arg2]; 

这会调用相应的objective-C函数,你c在该函数中调用你的主UI线程。

你可以创建一个单例类并在初始化时将它赋给void指针,然后在你的C函数中做需要的事情。

+0

我尝试了其他解决方案,它的工作。不过,你的看起来也会起作用。谢谢你的时间。 – 2011-05-11 12:58:47

+0

谢谢你为我工作。 – lppier 2012-11-19 10:36:45