I'm fairly new to iOS development but I'm starting to grasp some of the more complicated concepts. I currently have an application that implements an AVCam to capture video. The AVCam is created on a separate thread, but uses a view that is in my main xib file. When the camera is done capturing, it calls a complete function in my ViewController class. Within the complete function I call a number of other functions that update the UI as well as a few NSLogs. Everything seems to work fine, I see the logs in the console immediately, but the UI takes another 3 seconds to update. I've tried using instruments to find the offending code, but I can't seem to find it. Is there another way to determine what is blocking by UI?
我是iOS开发的新手,但我开始掌握一些更复杂的概念。我目前有一个实现AVCam捕获视频的应用程序。 AVCam是在单独的线程上创建的,但使用的是我的主xib文件中的视图。当摄像头完成捕获时,它会在我的ViewController类中调用一个完整的函数。在完整的函数中,我调用了许多其他函数来更新UI以及一些NSLog。一切似乎工作正常,我立即在控制台中看到日志,但UI需要另外3秒钟来更新。我已经尝试使用工具来查找有问题的代码,但我似乎无法找到它。是否有另一种方法来确定UI阻塞的内容?
Here is the code called when the recording is complete;
这是录制完成时调用的代码;
-(void)movieRecordingCompleted{
[HUD hide:YES];
NSLog(@"movieRecordingCompleted");
[self showModalViewController];
NSString *pathToMovie = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/Movie.mov"];
NSLog(@"pathToMovie: %@", pathToMovie);
pathToTreatedVid = pathToMovie;
NSLog(@"File Save Called");
UISaveVideoAtPathToSavedPhotosAlbum(pathToMovie, nil, NULL, NULL);
}
Everything is logged immediately, but the progress HUD and the modal view controller don't trigger for about 2 - 5 seconds, it's very strange.
一切都被立即记录,但进度HUD和模态视图控制器不会触发大约2-5秒,这很奇怪。
Here is the before and after state of the threads (when it is frozen vs when it becomes unfrozen).
这是线程的前后状态(当它被冻结时与它解冻时)。
4 个解决方案
#1
40
Try to Pause program execution (there is a button for that in bottom panel of Xcode
, the third one)
尝试暂停程序执行(在Xcode的底部面板中有一个按钮,第三个)
- Then look at left panel (
Navigator panel
), - 然后看左侧面板(Navigator面板),
- Find
Debug Navigator
- 查找Debug Navigator
- Find thread with
main
function, and mb you can figure out by methods in this thread, what takes so long to update your UI. The method that are working right now is the top black one usually(with grey colour listedobj-c
internal methods). - 使用main函数查找线程,并且您可以通过此线程中的方法找出mb,更新UI需要花费很长时间。现在正在使用的方法通常是顶部黑色(灰色列出了obj-c内部方法)。
#3
4
You can use the System Trace tool in Instruments by running your App in profile mode. Then you will get a detailed run down of all the threads in the system along with stack traces at each scheduling event the thread goes through.
您可以通过在配置文件模式下运行应用程序来使用Instruments中的系统跟踪工具。然后,您将获得系统中所有线程的详细运行以及线程经历的每个调度事件中的堆栈跟踪。
There is a great video from the 2016 WWDC System Trace in Depth which will walk you through debugging a blocked thread issue.
2016 WWDC System Trace in Depth中有一个很棒的视频,它将指导您调试阻塞的线程问题。
This is much better than the Time Profiler instrument since, that tool works based off of taking samples of what is running on the CPU at intervals. However, if your thread is blocked, it isn't running on the CPU, so - it will not be sampled. You might have your main thread blocked for a whole second but it won't show up in Time Profiler.
这比Time Profiler仪器要好得多,因为该工具的工作原理是每隔一段时间对CPU上运行的内容进行采样。但是,如果您的线程被阻塞,它不会在CPU上运行,因此 - 它不会被采样。您的主线程可能会被阻塞一整秒,但它不会显示在Time Profiler中。
#4
-9
I like using this function:
我喜欢使用这个功能:
sleep(x);
where "x" is the number of seconds...it will simply block whatever thread it's run on for that number of seconds. If your UI freezes, you know you blocked the main thread and thus that code is being run on the main thread (whether you intended that or not). Try placing this call in different places in your code and it should help you diagnose what's going on. Hope that helps.
其中“x”是秒数...它将简单地阻止它在该秒数上运行的任何线程。如果您的UI冻结,您知道您阻止了主线程,因此该代码正在主线程上运行(无论您是否打算这样做)。尝试将此调用放在代码中的不同位置,它可以帮助您诊断正在发生的事情。希望有所帮助。
#1
40
Try to Pause program execution (there is a button for that in bottom panel of Xcode
, the third one)
尝试暂停程序执行(在Xcode的底部面板中有一个按钮,第三个)
- Then look at left panel (
Navigator panel
), - 然后看左侧面板(Navigator面板),
- Find
Debug Navigator
- 查找Debug Navigator
- Find thread with
main
function, and mb you can figure out by methods in this thread, what takes so long to update your UI. The method that are working right now is the top black one usually(with grey colour listedobj-c
internal methods). - 使用main函数查找线程,并且您可以通过此线程中的方法找出mb,更新UI需要花费很长时间。现在正在使用的方法通常是顶部黑色(灰色列出了obj-c内部方法)。
#2
#3
4
You can use the System Trace tool in Instruments by running your App in profile mode. Then you will get a detailed run down of all the threads in the system along with stack traces at each scheduling event the thread goes through.
您可以通过在配置文件模式下运行应用程序来使用Instruments中的系统跟踪工具。然后,您将获得系统中所有线程的详细运行以及线程经历的每个调度事件中的堆栈跟踪。
There is a great video from the 2016 WWDC System Trace in Depth which will walk you through debugging a blocked thread issue.
2016 WWDC System Trace in Depth中有一个很棒的视频,它将指导您调试阻塞的线程问题。
This is much better than the Time Profiler instrument since, that tool works based off of taking samples of what is running on the CPU at intervals. However, if your thread is blocked, it isn't running on the CPU, so - it will not be sampled. You might have your main thread blocked for a whole second but it won't show up in Time Profiler.
这比Time Profiler仪器要好得多,因为该工具的工作原理是每隔一段时间对CPU上运行的内容进行采样。但是,如果您的线程被阻塞,它不会在CPU上运行,因此 - 它不会被采样。您的主线程可能会被阻塞一整秒,但它不会显示在Time Profiler中。
#4
-9
I like using this function:
我喜欢使用这个功能:
sleep(x);
where "x" is the number of seconds...it will simply block whatever thread it's run on for that number of seconds. If your UI freezes, you know you blocked the main thread and thus that code is being run on the main thread (whether you intended that or not). Try placing this call in different places in your code and it should help you diagnose what's going on. Hope that helps.
其中“x”是秒数...它将简单地阻止它在该秒数上运行的任何线程。如果您的UI冻结,您知道您阻止了主线程,因此该代码正在主线程上运行(无论您是否打算这样做)。尝试将此调用放在代码中的不同位置,它可以帮助您诊断正在发生的事情。希望有所帮助。