ARKit模板Xcode项目Main Thread Checker日志控制台 [英] ARKit template Xcode project Main Thread Checker log console

查看:59
本文介绍了ARKit模板Xcode项目Main Thread Checker日志控制台的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I just started a new Xcode ARKit project and ran it on a physical device but in the console I'm getting this output:

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

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

My question to you guys is why I'm getting this output? and what it means ?

非常感谢您的帮助.

推荐答案

(您当然可以禁用检查器,但有时它会有所帮助.检查

(Of course you can disable checker, but sometimes it can be helpful. Check https://stackoverflow.com/a/45689250/7183675 for this.)

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

Error is inside Apple framework, so only way I found do work around it was subclassing UIApplication class and check application state on main thread this way:

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

1) Add main.swift file (this name is really important!) with these lines

import UIKit

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

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

2) Remove @UIApplicationMain from MyDelegateClass if it was there or project wont compile because of multiple entry points

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

3) In MyApplicationClass.swift add this:

    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,因此不会发生问题.

Now you are calling UIApplication.applicationState on main thread, so issue won't occur.

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

Well, there is one more issue. If CMMotionManager is initialized from main thread then if will block main thread and wait for UIApplication.State. That means deadlock. In this case you can't set your semaphore. Only way to return credible state avoiding deadlock would be implementing application state this way:

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
        }
    }
}

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

Personally I don't like last solution, but I wasn't able to find another workaround

这篇关于ARKit模板Xcode项目Main Thread Checker日志控制台的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆