Xcode11 創(chuàng)建的項(xiàng)目運(yùn)行閃退或黑屏怎么解決?

1. 問題及原因

1.1 問題

????????首先聲明一下這里說的問題是針對(duì)通過代碼的方式來進(jìn)入程序而不是通過Storyboard。通過Xcode11之前的版本創(chuàng)建項(xiàng)目后,將AppDelegate.m文件中的application: didFinishLaunchingWithOptions:方法的實(shí)現(xiàn)改為下面的代碼就可以通過代碼設(shè)置rootViewController來啟動(dòng)程序了。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
    self.window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds];
    self.window.backgroundColor = UIColor.whiteColor;
    [self.window makeKeyAndVisible];
    
    self.window.rootViewController = [ViewController new];
    
    return YES;
}

????????但是當(dāng)我們用Xcode11創(chuàng)建項(xiàng)目通過同樣的方式來啟動(dòng)時(shí),發(fā)現(xiàn)程序閃退了,原因如下圖所示:


運(yùn)行報(bào)錯(cuò)
1.2 造成這個(gè)問題的原因

????????我們發(fā)現(xiàn),通過Xcode11創(chuàng)建的工程除了有AppDelegate這個(gè)類文件,還多出來一個(gè)SceneDelegate類文件。多出來的這個(gè)類時(shí)用來干嘛的呢?這是iPadOS帶來的用來支持多窗口的。
????????在iOS13之前,Appdelegate的職責(zé)全權(quán)處理App生命周期和UI生命周期。
????????而在iOS 13之后就發(fā)生了變化,UI生命周期變成由SceneDelegate來負(fù)責(zé),而Appdelegate負(fù)責(zé)APP的生命周期和SceneDelegate的生命周期。所以還是像之前那么處理的話就會(huì)出問題。

2. 解決方案一

????????如果我們項(xiàng)目中不需要支持多窗口,那我們就不需要用到SceneDelegate。
????????第一步,先將項(xiàng)目的Info.plist文件中的Application Scene Manifest這一項(xiàng)刪掉,然后刪掉SceneDelegate .hSceneDelegate.m文件(這兩個(gè)文件不刪也不會(huì)有影響)。

????????第二步,在AppDelegate .h文件中添加@property (nonatomic , strong) UIWindow *window;,然后將AppDelegate.m文件中的application: didFinishLaunchingWithOptions:方法的實(shí)現(xiàn)改為下面的代碼。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
    self.window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds];
    self.window.backgroundColor = UIColor.whiteColor;
    [self.window makeKeyAndVisible];
    
    self.window.rootViewController = [ViewController new];
    
    return YES;
}

????????第三步,經(jīng)過前面2步操作后運(yùn)行程序不會(huì)閃退了,但是發(fā)現(xiàn)黑屏,還需要將AppDelegate.m中的下面2個(gè)方法刪掉。這樣就可以正常啟動(dòng)程序了。

#pragma mark - UISceneSession lifecycle
- (UISceneConfiguration *)application:(UIApplication *)application configurationForConnectingSceneSession:(UISceneSession *)connectingSceneSession options:(UISceneConnectionOptions *)options {

    return [[UISceneConfiguration alloc] initWithName:@"Default Configuration" sessionRole:connectingSceneSession.role];
}


- (void)application:(UIApplication *)application didDiscardSceneSessions:(NSSet<UISceneSession *> *)sceneSessions {

}

3. 解決方案二

????????如果我項(xiàng)目中有多窗口開發(fā)相關(guān)的需求,或者需要保留SceneDelegate相關(guān)的內(nèi)容該怎么辦呢?首先我們這里不采用Storyboard的方式來啟動(dòng),先刪掉項(xiàng)目中Main.storyboard文件,然后打開項(xiàng)目的Info.plist文件,刪掉下圖用紅色框起來的兩項(xiàng)。

刪掉這兩項(xiàng)

????????然后在SceneDelegate.m文件的scene: willConnectToSession: options:方法中設(shè)置windowrootViewController,代碼如下所示:

- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions {

    self.window = [[UIWindow alloc] initWithWindowScene:(UIWindowScene *)scene];
    self.window.backgroundColor = UIColor.whiteColor;
    [self.window makeKeyAndVisible];
    
    self.window.rootViewController = [[UINavigationController alloc] initWithRootViewController:[ViewController new]];
}

????????這樣程序就可以在iOS 13的設(shè)備中正常運(yùn)行了,但是再iOS 13以下的設(shè)備上運(yùn)行會(huì)黑屏,所以還需要適配iOS 13以下的系統(tǒng)。首先在AppDelegate .h文件中添加@property (nonatomic , strong) UIWindow *window;,然后將AppDelegate.m文件中的application: didFinishLaunchingWithOptions:方法的實(shí)現(xiàn)改為下面的代碼。這樣就可以在所有系統(tǒng)上都能正常運(yùn)行了。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    
    // @available(iOS 13.0,*)表示iOS 13.0及以上的系統(tǒng),后面的*表示所有平臺(tái)
    if (@available(iOS 13.0,*)) {
        
    }else{
        self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
        self.window.backgroundColor = UIColor.whiteColor;
        [self.window makeKeyAndVisible];
        
        ViewController *vc = [ViewController new];
        
        self.window.rootViewController = [[UINavigationController alloc] initWithRootViewController:vc];
    }
    
    
    return YES;
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對(duì)...
    cosWriter閱讀 11,666評(píng)論 1 32
  • 用Xcode11創(chuàng)建項(xiàng)目新增SceneDelegate.h這個(gè)文件,AppDelegate文件結(jié)構(gòu)也發(fā)生變化,在A...
    i_MT閱讀 2,085評(píng)論 0 6
  • 今年的Xcode11無疑是近幾年變化最大之一的一個(gè)版本了。我也在升級(jí)Xcode11后各種踩坑,爽到淚水止不住流啊。...
    Invisible_He閱讀 8,682評(píng)論 3 10
  • iOS13 項(xiàng)目中的SceneDelegate類有什么作用?自從Xcode11發(fā)布以來,當(dāng)你使用新XCode創(chuàng)建一...
    樂Coding閱讀 31,114評(píng)論 14 61
  • 非原創(chuàng),收集,整理,覺得有用就羅列下為避免下次犯迷糊。 IOS 中的 AppDelegate.m/h 文件是很重要...
    西蜀閱讀 578評(píng)論 0 0

友情鏈接更多精彩內(nèi)容