viewDidAppear:在启动期间出现的模态视图控制器上调用两次

Posted

技术标签:

【中文标题】viewDidAppear:在启动期间出现的模态视图控制器上调用两次【英文标题】:viewDidAppear: called twice on modal view controller presented during startup 【发布时间】:2009-03-06 15:36:53 【问题描述】:

解决方案:在尝试在新项目中重新创建此错误以提交给 Apple 时,我发现它是 iPhone OS 2.1 特有的,针对 2.2 进行编译修复了该问题。斯蒂芬,感谢您的帮助;我会接受你的回答,因为如果错误仍然存​​在或者我不愿意为 2.2 编译它会起作用。


我有一个应用程序从根本上改变了它的数据库架构,需要我在代码中将旧式记录转换为新式记录。由于用户可能会在此应用程序中存储大量数据,因此我尝试显示带有进度条的模态视图控制器,同时将数据移植过来(即,作为用户看到的第一件事)。这个视图控制器的viewDidAppear: 开始一个数据库事务,然后启动一个后台线程来进行实际的移植,它偶尔使用performSelectorInMainThread:withObject:waitUntilDone: 来告诉前台线程更新进度条。

问题是,viewDidAppear: 被调用了两次。我注意到这一点是因为“启动事务”步骤失败并显示“数据库繁忙”消息,但设置断点表明它确实被调用了两次——一次由-[UIViewController viewDidMoveToWindow:shouldAppearOrDisappear:] 调用,另一次由-[UIViewController modalPresentTransitionDidComplete] 调用。这些名称似乎是私有 UIViewController 方法,所以我猜这要么是一个框架错误,要么我正在做一些 UIKit 不希望我做的事情。

两个相关的代码摘录(一些不相关的代码已经总结出来了):

- (void)applicationDidFinishLaunching:(UIApplication *)application 
    (register some default settings in NSUserDefaults)

    // doing this early because trying to present a modal view controller 
    // before the view controller is visible seems to break it
    [window addSubview:[self.navigationController view]];

    // this is the method that may present the modal view
    [self.databaseController loadDatabaseWithViewController:self.navigationController];

    if(!self.databaseController.willUpgrade) 
        [self restoreNavigationControllerState];
    

从我的 DatabaseController 类中:

- (void)loadDatabaseWithViewController:(UIViewController*)viewController 
    (open the new database)

    (compute the path the old database would live at if it existed)

    if([[NSFileManager defaultManager] fileExistsAtPath:oldDBPath]) 
        (open the old database)

        [viewController presentModalViewController:self animated:NO];
    

那么,我在这里搞砸了什么,还是应该向 Apple 提交错误报告?

【问题讨论】:

【参考方案1】:

我也在我的应用程序中看到了这一点。我从未得到完全证实,但我认为这就是正在发生的事情:

    加载根视图 加载模态视图 操作系统发送视图确实出现了步骤 1 中视图的通知 current 视图控制器(在本例中恰好是您的 DatabaseController 类)将其拾取 操作系统发送视图确实出现了模态视图的通知 当前视图控制器收到通知。在这种情况下,它与上次完全相同的控制器

就我而言,我只是重置了第一次调用 viewDidAppear: 时发生的事情。

在您的情况下,您会想到两个选项:一个静态变量,用于跟踪您是否已经开始升级;或者看一下启动前传入的UIView*参数。

【讨论】:

如上所述,我最终发现它已在 OS 2.2 中修复,但感谢您的建议。 没问题。很高兴看到“真实”的答案!

以上是关于viewDidAppear:在启动期间出现的模态视图控制器上调用两次的主要内容,如果未能解决你的问题,请参考以下文章

从 viewDidAppear 呈现时,模态弹出框控制器不显示其内容

呈现模态视图控制器时 iPhone 崩溃

iOS Root View Controller 的 viewDidAppear:在启动画面 (Default.png) 仍在屏幕上时调用

ReactJS:在superagent ajax请求期间显示带有加载消息的模态

启动应用程序后不出现模态视图

何时实际调用 viewDidLoad / viewDidAppear? [复制]