viewDidAppear:使用presentViewController时调用:animated:completion:

rob*_*408 2 objective-c uiviewcontroller grand-central-dispatch ios uiview-hierarchy

我有一个视图控制器,它查询Web服务是否应显示插页式广告.如果是这样,则使用presentViewController实例化并呈现另一个视图控制器:animated:completion:.根据这个答案文档,我假设viewDidAppear:当解雇所呈现的视图控制器(它自己做)时不会被调用.从概念上讲,无论如何,呈现视图控制器的视图永远不会从视图层次结构中删除,因此永远不需要"重新出现".我显然错了.那么发生了什么?为什么我所看到的与文档所说的不同?

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];

    [[AdService sharedAdService] adForSlotName:@"Main Interstitial" completionBlock:^(Ad *adForSlotName) {

        if(adForSlotName)
        {
            InterstitialAdViewController_iPhone *interstitialAdViewController = [[InterstitialAdViewController_iPhone alloc] init];
            interstitialAdViewController.ad = adForSlotName;

            dispatch_queue_t mainQueue = dispatch_get_main_queue();
            dispatch_async(mainQueue, ^{

                [self presentViewController:interstitialAdViewController animated:YES completion:^{}];

            });

            [interstitialAdViewController release];
        }
    }];
}

- (void)viewWillDisappear:(BOOL)animated
{
    [[AdService sharedAdService] clearAdForSlotName:@"Main Interstitial"];

    [super viewWillDisappear:animated];
}
Run Code Online (Sandbox Code Playgroud)

Aar*_*den 5

您链接的答案是关于viewDidDisappear的行为,而不是viewDidAppear.您链接的文档中的注释表示当呈现弹出框的子视图控制器被解除时,不会在呈现视图控制器上调用viewDidAppear .

在你的情况下,你正在呈现没有弹出窗口的子视图控制器,所以我读了doc的说明(在"证明规则"的方式的例外情况下)说当在子视图控制器是时应该在呈现视图控制器上调用viewDidAppear在你的情况下被驳回.

我认为你应该看到在显示子视图控制器时在父视图控制器上调用viewDidDisappear.我在一个最小的测试应用程序中尝试了这个,使用此代码呈现子视图控制器:

Parent *parent = [[Parent alloc] initWithNibName:nil bundle:nil];
[self.window setRootViewController:parent];
double delayInSeconds = 2.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
    Child *child = [[Child alloc] initWithNibName:nil bundle:nil];
    [parent presentViewController:child animated:YES completion:^{
        NSLog(@"Child presented");
        double delayInSeconds = 2.0;
        dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
        dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
            [parent dismissViewControllerAnimated:YES completion:^{
                NSLog(@"Child dismissed");
            }];
        });
    }];
});
Run Code Online (Sandbox Code Playgroud)

并且,在Parent和Child类中记录对各种与外观相关的回调的调用.这是我看到的序列:

使父视图控制器成为根视图控制器:

Parent viewWillAppear:
Parent viewDidAppear:
Run Code Online (Sandbox Code Playgroud)

呈现子视图控制器:

Parent viewWillDisappear:
Child viewWillAppear:
Child viewDidAppear:
Parent viewDidDisappear:
Child presented
Run Code Online (Sandbox Code Playgroud)

解雇子视图控制器:

Child viewWillDisappear:
Parent viewWillAppear:
Parent viewDidAppear:
Child viewDidDisappear:
Child dismissed
Run Code Online (Sandbox Code Playgroud)

所以这对我来说似乎是内部一致的 - 父子在呈现子视图控制器时获取消失调用,并在子视图控制器被解除时调用外观.这仍然与viewWillAppear记录的行为一致,因为我没有使用弹出窗口呈现子视图控制器.

我害怕我不知道为什么你的子视图控制器出现时你没有得到viewWill/DidDisappear调用.