ARKit template Xcode project Main Thread Checker log console

前端 未结 1 666
旧巷少年郎
旧巷少年郎 2021-01-14 02:26

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         


        
相关标签:
1条回答
  • 2021-01-14 03:10

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

    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) 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) Remove @UIApplicationMain from MyDelegateClass if it was there or project wont compile because of multiple entry points

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

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

    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

    0 讨论(0)
提交回复
热议问题