ios調用dismissViewController的一個小陷阱 – iPhone手機開發技術文章 iPhone軟體開發教學課程

我們的APP從啟動到進入主頁面,是通過presentViewController構造瞭一個ViewController序列,類似於首頁 -> 登陸頁 -> 啟動加載頁 -> 主頁面

其中,在啟動加載頁的viewDidAppear方法裡做瞭很多邏輯處理:

-(void) viewDidAppear:(BOOL)animated{
    
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){
        
        clientInfo = [YLSClientInfo new];
        
        if([clientInfo needInit]){
            [self mkdirAndDatabaseFile];
        }else{
            [self refreshVersion:[clientInfo currentVersion]];
        }
        
       // 各種處理邏輯
    });
}

然後進入主頁面之後,如果用戶退出登陸,就需要回到首頁,所以會在首頁上調用dismissViewController方法。原先的代碼類似這樣:

UIViewController *origin = self.presentingViewController.presentingViewController;
if([origin isMemberOfClass:[YLSLoginViewController class]]){
    origin = self.presentingViewController.presentingViewController.presentingViewController;
}
[origin dismissViewControllerAnimated:NO completion:nil];

預期的結果是,直接回到首頁,然後觸發首頁的viewDidAppear方法。實際上通過觀察console warning才發現,中間啟動加載頁的viewDidAppear方法也被調用瞭。登陸頁由於沒有寫viewDidAppear方法,所以沒有發現,但我猜測如果有的話,也一樣會被調用。似乎ViewController是按照順序一個接一個出棧的,所以每一個“之前的”ViewController的viewDidAppear方法應該都會被觸發

查瞭一下API,又上stackoverflow搜索瞭半天,似乎沒有辦法阻止這個默認行為。所以最後我的解決辦法是在中間的Controller上加瞭標記:

-(void) viewDidAppear:(BOOL)animated{
    
    // 如果是由於調用瞭dismiss而觸發瞭此方法,不進行初始化
    if(self.isDismissing){
        return;
    }
    
   // 初始化加載邏輯
}

YLSBootstrapViewController *bootstrapController = (YLSBootstrapViewController*)self.presentingViewController;
bootstrapController.isDismissing = YES;
                
UIViewController *origin = self.presentingViewController.presentingViewController;
if([origin isMemberOfClass:[YLSLoginViewController class]]){
    origin = self.presentingViewController.presentingViewController.presentingViewController;
}
[origin dismissViewControllerAnimated:NO completion:nil];

不知道大傢有沒有更好的做法

發佈留言