我在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)并返回查看控制器并再次设置标签。我之前没有尝试过自定义代表,所以如果你能帮助我解决我所缺少的问题会很棒。
答案 0 :(得分:1)
问题是你在主线程上调用sleep
。
以下是iOS应用的工作原理:
等到有趣的事情发生。
处理它。
返回第1步。
该应用程序有一个名为runloop的东西,可以从系统接收有关触摸,计时器等的消息。每次收到消息时,它都会运行一些代码,通常由您提供。当您调用sleep
函数时,它会挂起当前线程。当线程被挂起时,运行循环无法处理新事件,直到sleep
完成。
当您在屏幕上更改某些内容时,您会向运行循环添加一个事件,表示需要重新绘制屏幕。所以,这就是您的应用程序中发生的事情:
您可以更改标签文字。现在,重新绘制事件已添加到runloop。
您sleep
持续5秒,这意味着runloop无法处理新事件。
5秒后,线程唤醒并更改标签的文本。
Control终于返回到运行循环。
运行循环处理重绘事件,更改标签的文本。
如果任务需要是一个长期运行的任务,您可以在后台线程中执行:
-(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];
});
});
}