我有一个具有主线程的GUI应用程序,然后在用户单击“开始”按钮后,我使用NSOperation运行2个其他线程。现在一个线程计算某个值并更新它。我希望线程2做的是选择此值并更新UI。 如何从第二个线程获取IBOutlet Textfield值以在UI上更新?
例如: main.m ---处理UI并具有在用户点击开始按钮时启动2个线程的代码。
thread1.m - 计算一个特定值,并一直这样做,直到用户点击停止。
thread2.m - 需要使用此线程使用thread1.m计算的值更新main.m中的UI。
我无法完成thread2.m任务并更新UI。我的问题是如何定义IBOutlet并使用thread2 / 1中的值更新它,以便main.m可以访问此值并更新UI。我可以访问main.m中的实际变量,并可以使用NSLog将其打印出来。只是因为我不知道如何用这个值更新UI。因为我需要在main.m中使用IBMOutlet将它与应用程序中的UILabel绑定。有什么想法吗?感谢。
答案 0 :(得分:0)
你可以添加指向你的thread1.m和thread2.m文件的指针吗?然后使用构造函数方法或一些存取方法设置它们?
如果我理解你在你的例子中描述的情况,并假设你正在计算的是一个int(你可以根据需要修改):
添加一个访问者到thread1.m
-(int)showCurrentCalcValue
{
//Assume that you get calculatedValue from whereever else in your thread.
return calculatedValue;
}
然后添加到thread2.m
NSTextField *guiTextField;
Thread1 *thread1;
-(void) setThread: (Thread1 *aThread)
{
self.thread1 = aThread;
}
-(void) setGuiTextField: (NSTextField *aTextField)
{
self.guiTextField = aTextField;
}
-(void) updateGUI()
{
[guiTextField setStringValue: [thread1 showCurrentCalcValue]];
}
假设你的main.m类似于以下内容:
IBOutlet NSTextField *outputDisplay
-(void) setUpThreads()
{
Thread1 *thread1 = [[Thread1 alloc] init];
Thread2 *thread2 = [[Thread2 alloc] init];
[thread2 setGuiTextField: outputDisplay];
[thread2 setThread: thread1];
//Whatever else you need to do
}
然后只需要设置所有内容并调用线程中的方法。
答案 1 :(得分:0)
源代码文件无关紧要。你可以把所有这些东西放在一个文件中(不是那个好主意),问题就不会改变。重要的是课程。
课程不仅仅是代码包;你设计它们,命名它们,并定义每个类的责任范围。一个类和/或它的实例做某些事情;你定义那些东西是什么,不是。
编写NSOperation子类时,不要担心线程。不能保证他们甚至会在不同的线程上运行。每个操作只是一个工作单元;你写了一个操作来做一件事,不管是什么。
例如:main.m ---处理UI并具有启动2个线程的代码 -
操作
- 当用户点击开始按钮时。
thread1.m - 计算一个特定值,并一直这样做,直到用户点击停止。
这不是一件事;这是一个无限期的事情。
thread2.m - 需要使用此线程使用thread1.m计算的值更新main.m中的UI。
您不应该从(可能是)辅助线程触摸UI。请参阅Threading Programming Guide,尤其是“线程安全摘要”。
我不明白为什么它甚至应该被线程化。使用在主线程上运行的NSTimer,您可以更轻松地完成所有这些工作。
如果在主线程上“计算...特定值”是不合适的,那么您可以进行操作。您对计时器消息的响应将创建一个操作并将其添加到您的计算队列中。当用户点击停止时,该操作将在主线程上进行;使计时器无效并等待队列完成所有剩余的操作。
无论采用哪种解决方案,“thread2.m”都会完全消失。您对UI的更新将(并且必须)完全在主线程上发生。使用后一种解决方案,您甚至不必等到完成后;每次收到计时器消息时,都可以使用当前进度信息更新UI。