viewDidLoad上的CustomDelegate

时间:2015-03-22 16:37:41

标签: ios delegates

我在viewDidLoad上调用属于自定义委托类的方法,但它从[sampleProtocol startSampleProcess]开始,从sleep(5)开始,然后才显示view controller和label1。

CustomDelegate *sampleProtocol = [[CustomDelegate alloc]init];
sampleProtocol.delegate = self;
[self.label1 setText:@"Processing..."];
[sampleProtocol startSampleProcess];

startSampleProcess方法如下;

-(void)startSampleProcess{

    sleep(5);

    [self.delegate processCompleted];
}

processCompleted方法也在下面;

-(void)processCompleted{
    [self.label1 setText:@"Process Completed"];
}

它只是在viewcontroller上设置一个标签,转到另一个类并做一些简单的事情(etc:sleep)并返回查看控制器并再次设置标签。我之前没有尝试过自定义代表,所以如果你能帮助我解决我所缺少的问题会很棒。

1 个答案:

答案 0 :(得分:1)

问题是你在主线程上调用sleep

以下是iOS应用的工作原理:

  1. 等到有趣的事情发生。

  2. 处理它。

  3. 返回第1步。

  4. 该应用程序有一个名为runloop的东西,可以从系统接收有关触摸,计时器等的消息。每次收到消息时,它都会运行一些代码,通常由您提供。当您调用sleep函数时,它会挂起当前线程。当线程被挂起时,运行循环无法处理新事件,直到sleep完成。

    当您在屏幕上更改某些内容时,您会向运行循环添加一个事件,表示需要重新绘制屏幕。所以,这就是您的应用程序中发生的事情:

    1. 您可以更改标签文字。现在,重新绘制事件已添加到runloop。

    2. sleep持续5秒,这意味着runloop无法处理新事件。

    3. 5秒后,线程唤醒并更改标签的文本。

    4. Control终于返回到运行循环。

    5. 运行循环处理重绘事件,更改标签的文本。

    6. 如果任务需要是一个长期运行的任务,您可以在后台线程中执行:

      -(void)startSampleProcess {
          dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_NORMAL, 0) ^{  //run this code in the background so it doesn't block the runloop
              sleep(5);
              dispatch_async(dispatch_get_main_thread(), ^{    //after the task is done, call the delegate function back on the main thread since UI updates need to be done on the main thread
                  [self.delegate processCompleted];
              });
          });
      }