为啥一个简单的模态视图控制器在呈现和关闭时会滞后?

Posted

技术标签:

【中文标题】为啥一个简单的模态视图控制器在呈现和关闭时会滞后?【英文标题】:Why would a simple modal view controller lag when presented and dismissed?为什么一个简单的模态视图控制器在呈现和关闭时会滞后? 【发布时间】:2013-06-03 17:50:55 【问题描述】:

我的应用程序的主视图是 UIImagePickerController 相机视图。 当应用程序变得活跃时(在 didBecomeActive 中),我展示了一个模式视图控制器,它显示了从网络请求生成的一些设置。 (请注意,出于调试目的,我取出了网络请求,目前只显示一个虚拟视图)

模态视图动画流畅,但加载后冻结 3 秒然后正常响应。关闭视图后(动画也很流畅),我的图像选择器控制器暂停 2 秒,然后正常恢复。

我已经从模态视图控制器中删除了所有功能,以确保没有操作阻塞主线程。我正在展示最基本的控制器,但仍然会得到不稳定的用户界面。我怀疑这是来自我的呈现视图控制器调用 viewDidLoad/Unload 或类似的东西,但我的搜索没有给我任何关于在显示模式视图时在呈现视图控制器中调用哪些委托方法的信息。

我的问题可以通过回答来解决:

显示模式视图时,在演示者中调用了哪些委托方法? (如果有的话^)我怎么能不调用这些方法,或者让它们运行更顺畅? 与模态视图控制器相关的常见陷阱有哪些?

【问题讨论】:

你能在展示这个视图控制器的地方添加一些代码吗?不看代码很难说什么 我的presentViewControllerAnimated:completion: 是我的主视图控制器的didBecomeActive 函数中唯一的东西。在我的 viewDidLoad 中有很多初始化,在 viewDidUnload 中有很多释放......这就是为什么我在呈现模态视图控制器时试图忽略这些 【参考方案1】:

这可能是因为您在主线程中进行了大量处理(通常当 UI 停止时,这是因为主线程处理)。尽量给我们一些代码,特别是你认为最繁重的处理代码!对不起我糟糕的英语:P! 尝试使用

将最繁重的代码分派到另一个线程
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^
    //your heavy code here =)
);

问候, 卢卡斯

【讨论】:

【参考方案2】:

调用了多个方法。 ViewDidLoad ViewWillAppear ViewDidAppear ViewWillDisappear ViewDidDisappear。检查所有这些方法。另外,检查您创建的任何子视图,看看他们是否在他们的线程上做任何事情,涉及我所说的方法中的图像加载。模拟器和测试设备中也会出现这种情况吗?

ModalViewControllers 没有太多陷阱,但要了解在导航堆栈之类的东西上分配了多少视图,以及在彼此之上有多少视图。当你摆脱模态视图控制器时,你会调用dismissviewcontroller吗?

【讨论】:

是的,我打电话给dismissViewControllerAnimated: completion:nil。您知道在呈现模态视图时挂起这些委托方法的任何(简单)方法吗? @user,如果你没有在它们中做任何缓慢的事情,就不应该暂停这些方法。它们可能不是您的问题的原因。【参考方案3】:

可能会导致一些轻微延迟的一件事是每次都从头开始重新加载相同的 viewController。

BProfileTableViewController * _profileViewController = [[UIStoryboard storyboardWithName:@"Profile" bundle:[NSBundle chatUIBundle]] instantiateInitialViewController];
UINavigationController * profileNavigationController = [[UINavigationController alloc] initWithRootViewController:profileViewController];
[self.navigationController presentViewController:profileNavigationController animated:YES completion:nil];

您可以在此处看到,如果这是在 tableView 上单击,那么每次应用程序都需要再次创建 viewController。相反,如果我们只是重用视图,那么它会消除一些滞后。

在头文件中添加这个

BProfileTableViewController * _profileView;

然后模态视图加载代码变为:

// Open the users profile
if (!_profileView) 
    _profileView = [[UIStoryboard storyboardWithName:@"Profile" bundle:[NSBundle chatUIBundle]] instantiateInitialViewController];


UINavigationController * profileNavigationController = [[UINavigationController alloc] initWithRootViewController:_profileView];
[self.navigationController presentViewController:profileNavigationController animated:YES completion:nil];

这意味着我们只是重新加载视图而不是重新创建视图

【讨论】:

以上是关于为啥一个简单的模态视图控制器在呈现和关闭时会滞后?的主要内容,如果未能解决你的问题,请参考以下文章

为啥关闭视图控制器不会从内存中清除呈现的控制器?

如何从 appdelegate 呈现和关闭模态视图?

关闭从模态呈现的视图控制器翻转的视图控制器

如何从模态视图控制器调用呈现视图控制器的方法

视图控制器以模态方式呈现/关闭时的通知?

呈现/关闭包含表格的模态视图控制器会使表格下降