GYBootingProtection icon indicating copy to clipboard operation
GYBootingProtection copied to clipboard

StoryBoard构建window问题

Open zhao0 opened this issue 9 years ago • 3 comments

/** 
 * 对于代码构建 UI 的项目一般在 didFinishLaunch 方法中初始化 window,
 * 想在 swizzling 方法中 present alertController 需要自己先初始化 window 并提供一个 rootViewController
 */
- (void)presentAlertViewController:(UIAlertController *)alertController {
    if (![self hasStoryboardInfo]) {
        self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
        self.window.rootViewController = [[UIViewController alloc] init];
    }
    [self.window makeKeyAndVisible];
    [self.window.rootViewController presentViewController:alertController animated:YES completion:nil];
}

使用storyboard构建的window,在presentAlertViewController的时候 [self.window makeKeyAndVisible]就把window展示出来了,导致rootViewController被初始化,业务代码就被执行了,而且,如果是使用storyboard构建的window,我们无法掌控这个window什么时候被初始化,建议使用者手动初始化window

zhao0 avatar Jul 29 '16 14:07 zhao0

@zhao0 你说的有道理,按现在的写法,在使用 storyboard 的情况下如果 rootViewController 的初始化方法(包括 viewDidLoad、viewWillAppear、viewDidAppear 等方法)中有导致 crash 的逻辑,那在弹出提示修复窗口前 App 就 crash 了,永远都无法弹出提示窗口,也就无法修复了。不过作为第三方库来说,我们不该要求库的使用者手动初始化 window。其实我们只是需要一个 controller 来 present 一个 alert controller,在使用 storyboard 的情况下也完全可以自定义一个 controller 作为 rootController 用来 present alert controller,只要在完成修复之后把 rootController 改回来就好了。

sheepy1 avatar Jul 30 '16 17:07 sheepy1

@liuslevis 我提了个 PR 来解决这个问题,可以看一下 :)

sheepy1 avatar Jul 30 '16 18:07 sheepy1

@sheepy1 rootViewController init的时候也有可能crash

zhao0 avatar Jul 31 '16 03:07 zhao0