我如何重构我的代码在主线程上调用AppDelegate?

我最近开始将我的项目从Swift3 / Xcode8迁移到Swift4 / Xcode9。 我的应用程序在运行时崩溃,因为主线程清理程序只允许在主线程上访问UIApplication.shared.delegate ,导致启动时崩溃。 我有下面的代码,在Swift 3中工作正常 –

 static var appDelegate: AppDelegate { return UIApplication.shared.delegate as! AppDelegate; } 

我的代码中的其他类可以访问appDelegate。 我需要找出一种方法来从主线程返回UIApplication.shared.delegate

注意 :从访问appDelegate位置使用DispatchQueue.main.async{}块不是一个选项。 只需要在static var appDelegate声明中使用它。

寻找一个聪明的解决方法。

相关的崩溃消息:

主线程检查器:UI API在后台线程上调用: – [UIApplication delegate] PID:1094,TID:30824,线程名称:(none),队列名称:NSOperationQueue 0x60400043c540(QOS:未知),QoS:0

通过使用调度组解决。

 static var realDelegate: AppDelegate?; static var appDelegate: AppDelegate { if Thread.isMainThread{ return UIApplication.shared.delegate as! AppDelegate; } let dg = DispatchGroup(); dg.enter() DispatchQueue.main.async{ realDelegate = UIApplication.shared.delegate as? AppDelegate; dg.leave(); } dg.wait(); return realDelegate!; } 

并把它称为别的地方

 let appDelegate = AppDelegate(). realDelegate! 

一个可能的解决scheme是使appDelegate创build应用程序委托时初始化的AppDelegate类的静态存储属性:

 @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? static var appDelegate: AppDelegate! override init() { super.init() AppDelegate.appDelegate = self } // ... } 

然后应用程序委托可以被检索为

  AppDelegate.appDelegate 

从任何线程。

(应用程序委托的一个实例是在应用程序启动时调用的UIApplicationMain()创build的,这意味着该属性在应用程序运行循环启动时被初始化。