可可线是难以置信的

时间:2012-03-07 06:18:28

标签: objective-c ios multithreading cocoa concurrency

简而言之,我想在Objective-C cocoa中编写与以下Java伪代码相同的函数:

public class MainClass
{
    public void mainmethod() //Gets called at start of program
    {
        UILabel label = CreateAButton();
        new DaemonClass(label).start();
        //Do things without being interrupted by the Daemon class sleeping or lagging
    }
}

public class DaemonClass extends Thread
{
    public UILabel label;
    public DaemonClass(UILabel lbl)
    {
        setDaemon(true);
        label = lbl;
    }

    public void run()
    {
        int i = 0;
        while(true)
        {
            i++;
            i = i%2;
            UILabel.setText("" + i);
            Thread.sleep(1000);
        }
    }
}

换句话说......我想生成一个可以尽可能慢的守护程序线程,而不会中断任何其他线程的进度或速度,包括主要线程。

我尝试过使用Dispatch Queue以及NSThread等内容。

当使用其中任何一个时,我试图创建一个简单的标签转换器线程,将标签的文本从1无限地切换到0。在我看来,用户可以在启动时随机选择锁定为1或0。

当使用其中任何一个并尝试使用[NSThread sleepForTimeInterval:1];时,线程将在sleepForTimeInterval调用之后停止一起执行。

此外,在浏览了文档后,我发现在[NSThread sleep...正在睡觉时没有调用运行循环的事实!

如果有任何帮助,我正在使用- (void)viewDidLoad;方法调用我的帖子。

我的问题是:

如何阻止[NSThread sleepForTimeInterval:1];崩溃我的线程,或者: 如何启动调用方法或代码块的守护程序线程(最好是代码块!)

P.S。如果它有任何区别,这适用于iOS

2 个答案:

答案 0 :(得分:1)

您遇到问题的原因很可能是UIKit不是线程安全的,即您只能使用主线程中的UILabel。最简单的方法是使用GCD将主队列(与主线程相关联)上的块排入队列:

dispatch_async(dispatch_get_main_queue(), ^{
    myLabel.text = @"whatever";
});

答案 1 :(得分:0)

首先,你无法在后台线程中管理UIKit。要将文本设置为UILabel,您需要使用主线程。

根据您想要实现的任务类型判断,您应该使用NSTimer。您可以设置应该调用的时间间隔,并随时停止和恢复它。

@property (strong, nonatomic) NSTimer *timer; //in your .h file

- (void)startChangingLabelText {
  self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0
                                                target:self
                                              selector:@selector(checkTime:)
                                              userInfo:nil
                                               repeats:YES];
}

- (void)stopChangingLabelText {
  [timer invalidate], self.timer = nil;
}

    - (void)checkTime:(NSTimer *)timer {
      int rand = arc4random() % 2;
      if (rand)
        label.text = @"true";
      else
        label.text = @"false";
    }