ARKit模板Xcode项目Main Thread Checker日志控制台

时间:2018-11-19 17:34:25

标签: ios

我刚刚启动了一个新的Xcode ARKit项目,并在物理设备上运行了它,但是在控制台中,我得到了以下输出:

Main Thread Checker: UI API called on a background thread: -[UIApplication applicationState]
PID: 4865, TID: 2042694, Thread name: com.apple.CoreMotion.MotionThread, Queue name: com.apple.root.default-qos.overcommit, QoS: 0
Backtrace:
4   libobjc.A.dylib                     0x00000001d7477894 <redacted> + 56
5   CoreMotion                          0x00000001ddcf4760 CoreMotion + 304992
6   CoreMotion                          0x00000001ddcf4c94 CoreMotion + 306324
7   CoreMotion                          0x00000001ddcf4ba4 CoreMotion + 306084
8   CoreMotion                          0x00000001ddd26384 CoreMotion + 508804
9   CoreMotion                          0x00000001ddd263e4 CoreMotion + 508900
10  CoreFoundation                      0x00000001d820d4d8 <redacted> + 28
11  CoreFoundation                      0x00000001d820cdbc <redacted> + 276
12  CoreFoundation                      0x00000001d82080c0 <redacted> + 2324
13  CoreFoundation                      0x00000001d8207494 CFRunLoopRunSpecific + 452
14  CoreFoundation                      0x00000001d82081f8 CFRunLoopRun + 84
15  CoreMotion                          0x00000001ddd25d1c CoreMotion + 507164
16  libsystem_pthread.dylib             0x00000001d7e829c8 <redacted> + 132
17  libsystem_pthread.dylib             0x00000001d7e82924 _pthread_start + 52
18  libsystem_pthread.dylib             0x00000001d7e8addc thread_start + 4
2018-11-19 09:21:42.623520-0800 MyFirstARKitApp[4865:2042694] [reports] Main Thread Checker: UI API called on a background thread: -[UIApplication applicationState]
PID: 4865, TID: 2042694, Thread name: com.apple.CoreMotion.MotionThread, Queue name: com.apple.root.default-qos.overcommit, QoS: 0
Backtrace:
4   libobjc.A.dylib                     0x00000001d7477894 <redacted> + 56
5   CoreMotion                          0x00000001ddcf4760 CoreMotion + 304992
6   CoreMotion                          0x00000001ddcf4c94 CoreMotion + 306324
7   CoreMotion                          0x00000001ddcf4ba4 CoreMotion + 306084
8   CoreMotion                          0x00000001ddd26384 CoreMotion + 508804
9   CoreMotion                          0x00000001ddd263e4 CoreMotion + 508900
10  CoreFoundation                      0x00000001d820d4d8 <redacted> + 28
11  CoreFoundation                      0x00000001d820cdbc <redacted> + 276
12  CoreFoundation                      0x00000001d82080c0 <redacted> + 2324
13  CoreFoundation                      0x00000001d8207494 CFRunLoopRunSpecific + 452
14  CoreFoundation                      0x00000001d82081f8 CFRunLoopRun + 84
15  CoreMotion                          0x00000001ddd25d1c CoreMotion + 507164
16  libsystem_pthread.dylib             0x00000001d7e829c8 <redacted> + 132
17  libsystem_pthread.dylib             0x00000001d7e82924 _pthread_start + 52
18  libsystem_pthread.dylib             0x00000001d7e8addc thread_start + 4

我对你们的问题是为什么我要得到这个输出?到底是什么意思?

非常感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

(您当然可以禁用检查器,但有时它会有所帮助。为此检查https://stackoverflow.com/a/45689250/7183675。)

错误在Apple框架内部,所以我发现只能解决的方法是将UIApplication类子类化,并以此方式检查主线程上的应用程序状态:

1)在这些行中添加main.swift文件(此名称确实很重要!)

import UIKit

    UIApplicationMain(
        CommandLine.argc,
        CommandLine.unsafeArgv,
        NSStringFromClass(MyApplicationClass.self),
        NSStringFromClass(MyDelegateClass.self)
    )

2)如果@UIApplicationMainMyDelegateClass中,或者由于多个入口点而导致项目无法编译,则将其删除。

3)在MyApplicationClass.swift中添加以下内容:

    import UIKit

    class MyApplicationClass: UIApplication {
    let semaphore = DispatchSemaphore(value: 0)
    override var applicationState: UIApplication.State {
        if Thread.current == Thread.main {
            return super.applicationState
        }

        var toReturn =  UIApplication.State.inactive

        DispatchQueue.main.async { [weak self] in
            guard let self = self else {return}
            toReturn = self.superAppState()
            self.semaphore.signal()
        }
        semaphore.wait()
        return toReturn
    }

    private func superAppState() -> UIApplication.State {
        return super.applicationState
    }
}

现在您正在主线程上调用UIApplication.applicationState,因此不会发生问题。

嗯,还有一个问题。如果CMMotionManager是从主线程初始化的,则将阻塞主线程并等待UIApplication.State。那意味着僵局。在这种情况下,您无法设置信号量。返回可信状态以避免死锁的唯一方法是通过以下方式实现应用程序状态:

4)

import UIKit

        class MyApplicationClass: UIApplication {

    private static var configured = false

    private var state = UIApplication.State.inactive

    override var applicationState: UIApplication.State {
        if !MyApplicationClass.configured {
            MyApplicationClass.configured = true
            NotificationCenter.default.addObserver(self, selector: #selector(setStatus(_:)), name: UIApplication.didBecomeActiveNotification, object: nil)
            NotificationCenter.default.addObserver(self, selector: #selector(setStatus(_:)), name: UIApplication.willResignActiveNotification, object: nil)
            NotificationCenter.default.addObserver(self, selector: #selector(setStatus(_:)), name: UIApplication.willEnterForegroundNotification, object: nil)
            NotificationCenter.default.addObserver(self, selector: #selector(setStatus(_:)), name: UIApplication.didEnterBackgroundNotification, object: nil)
        }
        if Thread.current == Thread.main {
            return super.applicationState
        }
        return state
    }

    @objc func setStatus(_ notif: Notification) {
        switch notif.name {
        case UIApplication.didBecomeActiveNotification:
            state = .active
        case UIApplication.willResignActiveNotification:
            state = .inactive
        case UIApplication.willEnterForegroundNotification:
            state = .background
        case UIApplication.didEnterBackgroundNotification:
            state = .background
        default:
            state = .inactive
        }
    }
}

我个人不喜欢上一个解决方案,但是我找不到其他解决方法