我的iOS应用程序冻结但没有出现错误

时间:2014-01-29 09:27:28

标签: ios iphone multithreading ipad freeze

是否有人知道我需要检查应用程序是否在一段时间后冻结?我的意思是,我可以在iPhone屏幕上看到该应用程序,但没有视图响应。

我做了一些谷歌,我发现,我已经以某种方式阻止了主线程。

但我的问题是如何识别哪个方法导致主线程阻塞?有没有办法识别?

7 个答案:

答案 0 :(得分:21)

启动您的应用并等待它冻结。然后按Xcode中的“暂停”按钮。左侧窗格应显示当前正在运行的方法。

答案 1 :(得分:5)

通常,强烈建议在主线程上执行所有动画方法和界面操作,并在后台执行任务,例如从服务器下载数据等...

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    //here everything you want to perform in background

    dispatch_async(dispatch_get_main_queue(), ^{ 
        //call back to main queue to update user interface
    });
});

来源:http://www.raywenderlich.com/31166/25-ios-app-performance-tips-tricks

答案 2 :(得分:3)

设置冻结发生处的断点,并找出导致该行的那一行。

可能是,加载大数据,禁用控件,主线程重载,只需找出使用断点发生的位置并根据它进行纠正。

答案 3 :(得分:0)

我遇到了与此类似的错误,但这是出于不同的原因。我有一个按钮,可以对另一个包含TableView的ViewController进行搜索,但是只要执行搜索,应用程序就会冻结。

我的问题是,由于我的一个变量中有两个reloadData()观察者,我被无限次调用didSet。一旦我将此呼叫转移到其他地方,问题就解决了。

答案 4 :(得分:0)

在大多数情况下,这种情况发生在我要求无限次更改设计时。哪个功能可以做到?好吧,就是这个:

override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
    }

解决方案是添加条件,使viewDidLayoutSubviews内部的函数仅获得1次调用。

答案 5 :(得分:0)

我相信应该可以定期检查主线程是否被阻塞或冻结。您可以创建一个对象来执行此操作:

final class FreezeObserver {
    
    private let frequencySeconds: Double = 10
    private let acceptableFreezeLength: Double = 0.5
    
    func start() {
        DispatchQueue.global(qos: .background).async {
            
            let timer = Timer(timeInterval: self.frequencySeconds, repeats: true) { _ in
                
                var isFrozen = true
                
                DispatchQueue.main.async {
                    isFrozen = false
                }
                
                DispatchQueue.global(qos: .background).asyncAfter(deadline: .now() + self.acceptableFreezeLength) {
                    guard isFrozen  else { return }
                    
                    print("your app is frozen, so crash or whatever")
                }
            }
        
            let runLoop = RunLoop.current
            runLoop.add(timer, forMode: .default)
            runLoop.run()
        }
    }
}

答案 6 :(得分:0)

可能是另一个视图没有正确关闭,它阻止了用户交互!查看UI Debugger,查看顶层,看看有没有什么奇怪的东西。