实例化模态视图控制器会冻结应用程序 - Xcode 7可能存在问题

4

我在iOS应用中以模态方式呈现一个视图控制器。 问题是调用presentViewController:animated后没有崩溃,但应用程序会立即冻结。 统计数据显示CPU使用率为100%,甚至手动关闭应用程序之后使用率也不会降下来。

UIStoryboard *sb = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
CustomModalViewController *vvc = [sb instantiateViewControllerWithIdentifier:@"CustomModalViewController"];
if(!vvc){
    NSLog(@"ERROR!!! vvc is null");
}
NSLog(@"instantiate modal view controller");

vvc.providesPresentationContextTransitionStyle = YES;
vvc.definesPresentationContext = YES;
vvc.data = data;
NSLog(@"before presenting modal view controller");
[vvc setModalPresentationStyle:UIModalPresentationOverCurrentContext];
[self presentViewController:vvc animated:YES completion:nil];

我尝试在自定义类的viewDidLoad中打印一些调试语句,但是那些也没有被调用。我不明白为什么视图控制器没有显示。任何帮助将不胜感激。我想知道在什么情况下您的应用程序在推送视图控制器时会进入无限循环,或者是因为其他原因导致的?更新:在我升级到XCode 7之后出现了这个错误。不确定,但我猜测这可能是新SDK-UIKit或LLVM编译器的问题。我将我的项目复制到另一台安装Xcode 6.4的Mac上,错误消失了!我也没有更改任何可能导致问题的构建设置。如何继续进行?

它不起作用,你可能需要编写自定义转换来使背景半透明。 - Mukesh
如果您想要,我在这里分享了一个示例,以使背景透明。http://stackoverflow.com/a/32434166/3535583 - Mukesh
你在呼叫这段代码的时候是从哪个 presenting controller 呢?很可能是 presenting controller 出了问题。试着在呈现之前访问新控制器的视图,看看是否会卡住。let view=vvc.view 会强制调用 vvcviewDidLoad。如果它现在卡在这一行上,那么你的问题就在于 CustomModalViewController 中。很可能是在它的 viewDidLoad 中出了问题。你也可以暂停调试器,查看堆栈跟踪中的位置。 - Rory McKinnel
在UIViewController的loadViewIfRequired中,它会递归调用initWithCoder。 - Ajax
看到你的更新了。你尝试过删除应用程序,进行构建清理,完整构建,然后运行以防止应用程序安装出现问题吗? - Rory McKinnel
显示剩余7条评论
4个回答

6
好的,这很奇怪,但我希望能帮到你:我遇到了完全相同的问题,CPU 占用率跳到 100%,视图从未显示。在 Xcode 6.4 中完美运行。在 Xcode 7.1 中,在我调用的视图上,我有一个带有一些占位文本“注释:” 的 UITextView。我发现,如果清除占位符文本,则视图会加载,并且所有过程都会正常执行。如果占位符文本长度大于 9 个字符,则视图也会加载,并且过程会正常执行。如果占位符文本长度>0 且 <10,则无法使用。没有视图,CPU 占用率为 100%。我意识到这很奇怪,但希望能帮到你。像你一样,我没有任何错误或控制台输出可以展示,它只是旋转。

编辑:FYI,在 storyboard 中清空占位符文本,并在代码中设置它也可以解决这个问题,无论其长度如何。


天哪,就是这个!我尝试了很多方法,但这就是解决方案。同样的问题,Xcode 7.1,我在Storyboard上有一个UITextView,上面有占位符文本,并在我的视图控制器中设置它。对我来说,解决方案就是只清空Storyboard上的文本,并仅在代码中设置它。这就解释了为什么它会陷入NSString isEqualToString循环中。 - Will
这并没有给出根本原因,但我仍然接受它!在我的情况下也起作用了。 - Ajax
请为此问题找到一个合适的名称。它将把人们重定向到另一个问题的答案。 - Muhammad Asyraf
我有一个项目,之前是用Swift 3和Xcode 8.3开发的。现在我不得不转换到Xcode 11,但是当我呈现时,有几个控制器没有出现。CPU和内存升高,屏幕冻结,没有错误提示。但我没有看到任何UITextView。还有其他原因吗? - PoolHallJunkie

0

我也遇到了同样的问题。

我有一个带有默认字符串“Text”的UITextView,但是它会导致100%的CPU负载失败。我一直在代码中放置占位符,但是直到我从storyboard中删除了“Text”才起作用。

我的代码是在Xcode 6中开发的,我在使用Xcode 7构建的新应用程序修订版本后注意到了这个错误。


0

我遇到了与OP和答案中描述的完全相同的问题:

  1. 呈现一个视图控制器(在我的情况下是一个PageViewController
  2. 被呈现的视图控制器有一个按钮,当按下时会呈现另一个视图控制器以添加注释
  3. 在“注释”视图控制器被呈现时将应用程序移至后台。然后将其带回前景。
  4. 应用程序现在已经冻结。当连接到调试器时,它似乎无限期地冻结,但在生产中运行时会崩溃。 CPU占用率达到100%,内存使用量正在上升。

我最终追踪到这个问题是因为我的“Note”视图被设置为第一响应者。当我的视图出现时,通过override func viewWillAppear(_ animated: Bool),我将注释UITextView设置为成为第一响应者,noteTextView.becomeFirstResponder()

如果我删除了那行代码并且从未点击过注释字段,则我的应用程序将成功从后台恢复。

为了解决这个问题,我最终添加了观察器,以便在应用程序移动到后台和移动到前台时使注释文本视图成为第一响应者并放弃第一响应者。

    override func viewDidLoad() {
        super.viewDidLoad()
        //set up your view controller here. 

        NotificationCenter.default.addObserver(self, selector: #selector(self.appMovedToForeground), name: UIApplication.willEnterForegroundNotification, object: nil)

        NotificationCenter.default.addObserver(self, selector: #selector(self.appMovedToBackground), name: UIApplication.didEnterBackgroundNotification, object: nil)
    }

    @objc func appMovedToForeground() {
        self.noteTextView.becomeFirstResponder()
    }

    @objc func appMovedToBackground() {
        self.noteTextView.resignFirstResponder()
    }

我不确定是否应该采取其他措施来防止这个问题的发生,或者当应用程序进入后台时重新指定第一响应者是否是最佳实践,但这对我来说似乎是有效的。


0
我正在展示设置屏幕,所以
我转换了这个:
    private lazy var settingsVC: SettingsVC = {
    let controller = SettingsVC.fromStoryboard()
    settingsVC.delegate = self
    return controller
}()

翻译为:

private lazy var settingsVC = SettingsVC.fromStoryboard()

然后在呈现设置的控制器中稍后在视图加载时设置委托:

    override func viewDidLoad() {
    super.viewDidLoad()
    settingsVC.delegate = self
}

现在它可以工作了


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接