viewDidLoad 上的 CustomDelegate

CustomDelegate on viewDidLoad

我在 viewDidLoad 上调用属于自定义委托 class 的方法,但它从 [sampleProtocol startSampleProcess] 开始,从 sleep(5) 开始,然后才显示视图控制器和 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 上设置标签,转到另一个 class 并做一些简单的事情(等:睡眠),然后返回查看控制器并再次设置标签。我之前没有尝试过自定义委托,所以如果你能帮助我解决我所缺少的,那就太好了。

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

iOS 应用的工作原理如下:

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

  2. 处理一下。

  3. 返回步骤 1。

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

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

  1. 您更改标签文本。 运行循环中现在添加了重绘事件。

  2. sleep 5 秒,这意味着 运行 循环无法处理新事件。

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

  4. 控制终于回到 运行 循环。

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

如果任务需要是一个long-运行ning任务,你可以在后台线程中完成:

-(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];
        });
    });
}