aliyun / aliyun-oss-ios-sdk

iOS SDK for aliyun object storage service
Other
469 stars 321 forks source link

Main Thread Checker: UI API called on a background thread #203

Open ZenonHuang opened 5 years ago

ZenonHuang commented 5 years ago

Main Thread Checker: UI API called on a background thread: -[UIApplication applicationState] PID: 14352, TID: 3167824, Thread name: (none), Queue name: com.apple.root.default-qos, QoS: 0 Backtrace:

 -[UTSelfStaticsManager getAppState] + 60
-[UTSelfStaticsManager onEventForCrash] + 256
-[UTMCSystemHook appDIdEnterBackground:]_block_invoke.51 + 196
_dispatch_call_block_and_release + 24
_dispatch_client_callout + 16
_dispatch_queue_override_invoke + 876
 _dispatch_root_queue_drain + 372
 _dispatch_worker_thread2 + 156
_pthread_wqthread + 464
 start_wqthread + 4

请问什么时候能修复这个问题? 你们 hook 了进入后台方法,在里面做 UI 操作,现在我们 App 再次切回来,偶尔会引发卡顿。也没有办法看你们的代码调试问题。 希望尽快修复

ZenonHuang commented 5 years ago

我目前找到了办法,避免这个问题。

有需要的朋友可以找我 : )

Matthew1874 commented 5 years ago

@ZenonHuang 你好请问怎样解决了?

ZenonHuang commented 5 years ago

留你的邮箱给我,有空发代码给你

ArchimboldiMao commented 5 years ago

@ZenonHuang 你好,请问可否公开解决代码?

bluerainxty commented 5 years ago

@ZenonHuang 你好,能否分享一下解决方法,谢谢?我的邮箱是595282304@qq.com

Matthew1874 commented 5 years ago

@ZenonHuang 你好 我的邮箱是这个:670058571@qq.com 谢谢

WineKai commented 5 years ago

留你的邮箱给我,有空发代码给你

你好,能否发下解决方案。535750930@qq.com.谢谢。

ZenonHuang commented 5 years ago

已经发送给上面的各位,请查收。

ArchimboldiMao commented 5 years ago

@ZenonHuang 你好,我前面没有留邮箱,请发送一份给我。谢谢。 我的邮箱 archimboldi.mao@gmail.com

WineKai commented 5 years ago

这个warning好像不影响使用,当连接xcode10时 因为默认开启了main thread checker 所以会卡顿。关闭此选项或者不连xcode测试时没什么影响

wffkan commented 5 years ago

@WineKai 你好,我也遇到相似的问题,能否发下解决方案。409322456@qq.com.谢谢。

dklinzh commented 5 years ago
#if DEBUG
extension UIApplication {

    @objc
    private var __applicationState: UIApplication.State {
        if Thread.isMainThread {
            return self.__applicationState
        } else {
            var state = UIApplication.State.active
            let condition = NSCondition()
            condition.lock()
            DispatchQueue.main.async {
                state = self.__applicationState
                condition.signal()
            }
            condition.wait()
            return state
        }
    }

    /// FIXME: [UTSelfStaticsManager getAppState] called on a background thread.
    static func mainThreadApplicationState() {
        if let originalMethod = class_getInstanceMethod(UIApplication.self, #selector(getter: applicationState)),
            let swizzledMethod = class_getInstanceMethod(UIApplication.self, #selector(getter: __applicationState)) {
            method_exchangeImplementations(originalMethod, swizzledMethod)
        } else {

        }
    }
}
#endif
dklinzh commented 5 years ago

Swift 5 Updated:

#if DEBUG
extension UIApplication {

    private class ApplicationState {

        static let shared = ApplicationState()

        var current = UIApplication.State.inactive

        private init() {
            let center = NotificationCenter.default
            let mainQueue = OperationQueue.main
            center.addObserver(forName: UIApplication.didEnterBackgroundNotification, object: nil, queue: mainQueue) { (notification) in
                self.current = UIApplication.shared.applicationState
            }
            center.addObserver(forName: UIApplication.willEnterForegroundNotification, object: nil, queue: mainQueue) { (notification) in
                self.current = UIApplication.shared.applicationState
            }
            center.addObserver(forName: UIApplication.didFinishLaunchingNotification, object: nil, queue: mainQueue) { (notification) in
                self.current = UIApplication.shared.applicationState
            }
            center.addObserver(forName: UIApplication.didBecomeActiveNotification, object: nil, queue: mainQueue) { (notification) in
                self.current = UIApplication.shared.applicationState
            }
            center.addObserver(forName: UIApplication.willResignActiveNotification, object: nil, queue: mainQueue) { (notification) in
                self.current = UIApplication.shared.applicationState
            }
        }
    }

    @objc
    private var __applicationState: UIApplication.State {
        if Thread.isMainThread {
            return self.__applicationState
        } else {
            return ApplicationState.shared.current
        }
    }

    /// FIXME: -[UIApplication applicationState] called on a background thread.
    public static func mainThreadApplicationState() {
        if let originalMethod = class_getInstanceMethod(UIApplication.self, #selector(getter: applicationState)),
            let swizzledMethod = class_getInstanceMethod(UIApplication.self, #selector(getter: __applicationState)) {
            _ = ApplicationState.shared
            method_exchangeImplementations(originalMethod, swizzledMethod)
        } 
    }
}
#endif

UIApplication.mainThreadApplicationState() should be called in func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool of AppDelegate ONLY in Debug configuration.

WineKai commented 5 years ago

@WineKai 你好,我也遇到相似的问题,能否发下解决方案。409322456@qq.com.谢谢。

其实不影响使用,连着xcode调试时会卡,因为xcode默认开始mainthreadchecker ,关闭即可。问了阿里的技术人员,说只是个warning,不影响使用

17770030995 commented 5 years ago

@ZenonHuang 能不能发一份我邮箱,十分感谢!362175212@qq.com

ZenonHuang commented 5 years ago

既然内部有说不影响,那也就不怕什么了。你们如果比较在意,就做一个线上监控观察一下。 思路其实和上面类似,就是对代码进行 Hook.只不过我通过实验,找到了他们具体的类和方法。 对 UTMCSystemHookappDIdEnterBackground: 方法的实现做重新指向就可以了

jimmyWJJ commented 4 years ago

我目前找到了办法,避免这个问题。

有需要的朋友可以找我:)

@ZenonHuang 你好,我也遇到了此问题,麻烦分享一下解决方案,谢谢,邮箱18262385773@163.com

wangbo6886 commented 4 years ago

@ZenonHuang 你好麻烦也分享一份解决方案给我吧,谢谢了(940001909@qq.com)

sun881122 commented 4 years ago

@ZenonHuang 你好麻烦也分享一份解决方案给我吧,谢谢了(18701795075@163.com)

wgziOS commented 4 years ago

@ZenonHuang 你好 麻烦给我一份解决方案。谢谢你了。547256553@qq.com

GabrielOmarBatistuta commented 2 years ago

@ZenonHuang 你好 麻烦给我一份解决方案。非常感谢。tdh_005@163.com