问题
[UIApplication.sharedApplication.delegate.window …] 在Xcode11新建的项目中闪退。
抛出的异常如下:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[AppDelegate window]: unrecognized selector sent to instance 0x600003774260' terminating with uncaught exception of type NSException
原因
闪退的原因是找不到UIApplication.sharedApplication的delegate里面找不到window这个属性,所以闪退。
分析
Xcode11 新建的项目中和之前的Xcode新建的项目有一些区别,Xcode11新建的项目中,多了一个SceneDelegate来管理界面,包括Window等。而AppDelegate只负责应用程序的声明周期管理。
在Xcode12之前,使用UIApplication.sharedApplication.delegate.window可以获取到window这个实例是因为在AppDelegate中有window这个属性:
@interface AppDelegate : NSObject
@property (nonatomic, strong) UIWindow *window;
@end
Xcode 11创建的项目,AppDelegate里没有window这个属性,所以通过UIApplication.sharedApplication.delegate.window来取window这个属性是取不到的,所以闪退。
解决
解决办法存在很多种,如果还是想用之前的方式来获取Window的话,需要在AppDelegate中添加window属性,然后在给该属性附上值即可。
- AppDelegate添加window属性
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow * window;
@end
- 给AppDelegate添加window的引用
- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions {
// Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
// If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
// This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
self.window = [[UIWindow alloc] initWithWindowScene:(UIWindowScene *)scene];
self.window.backgroundColor = [UIColor whiteColor];
ViewController *naviRootVc = [[ViewController alloc] init];
UINavigationController *windowRootVc = [[UINavigationController alloc] initWithRootViewController:naviRootVc];
self.window.rootViewController = windowRootVc;
[self.window makeKeyAndVisible];
[UIApplication sharedApplication].delegate.window = self.window;
}