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

时间:2009-03-06 15:36:54

标签: iphone cocoa-touch uiviewcontroller modalviewcontroller app-startup

解决方案:在尝试在新项目中重新提交此错误以提交给Apple时,我发现它特定于iPhone OS 2.1,并且针对2.2进行编译可以解决问题。斯蒂芬,谢谢你的帮助;我会接受你的答案,因为如果bug仍然存在或者我不愿意为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 个答案:

答案 0 :(得分:3)

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

  1. 加载根视图
  2. 加载模态视图
  3. 操作系统发送视图确实显示了步骤1中视图的通知
  4. 当前视图控制器,在这个实例中恰好是您的DatabaseController类,然后选择它
  5. OS发送视图确实显示模态视图的通知
  6. 当前视图控制器获取通知。在这种情况下,它与上次完全相同的控制器
  7. 在我的情况下,我只是重置第一次调用viewDidAppear:时发生的事情。

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