viewDidAppear:在启动期间呈现的模态视图控制器上调用两次
解决方案:在尝试在新项目中重新创建此错误以提交给 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 提交错误报告?
Resolution: While trying to recreate this bug in a fresh project to submit to Apple, I discovered that it is specific to iPhone OS 2.1, and compiling for 2.2 fixes the problem. Stephen, thanks for your help; I'll be accepting your answer since it would have worked if the bug still existed or I wasn't willing to compile for 2.2.
I have an app which is radically changing its database schema in a way that requires me to transform old-style records to new-style ones in code. Since users may store a lot of data in this app, I'm trying to display a modal view controller with a progress bar while it ports the data over (i.e. as the very first thing the user sees). This view controller's viewDidAppear:
begins a database transaction and then starts a background thread to do the actual porting, which occasionally uses performSelectorInMainThread:withObject:waitUntilDone:
to tell the foreground thread to update the progress bar.
The problem is, viewDidAppear:
is being called twice. I noticed this because that "start a transaction" step fails with a "database busy" message, but setting a breakpoint reveals that it is indeed called two times—once by -[UIViewController viewDidMoveToWindow:shouldAppearOrDisappear:]
, and again by -[UIViewController modalPresentTransitionDidComplete]
. Those names appear to be private UIViewController methods, so I'm guessing this is either a framework bug, or I'm doing something UIKit isn't expecting me to do.
Two relevant code excerpts (some irrelevant code has been summarized):
- (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];
}
}
And from my DatabaseController class:
- (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];
}
}
So, is there something I'm screwing up here, or should I file a bug report with Apple?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我也在我的应用程序中看到了这个。 我从未完全确认过这一点,但我认为这就是发生的情况:
在我的例子中,我只是重置了第一次调用
viewDidAppear:
时发生的情况。在您的情况下,我会想到两个选项:一个静态变量来跟踪您是否已经开始升级; 或者查看启动前传入的
UIView*
参数。I saw this in my app too. I never got it entirely confirmed, but I think this is what's happening:
In my case I just reset what happened in the first call to
viewDidAppear:
.In your case two options spring to mind: a static variable to track whether you've started the upgrade already; or look at the
UIView*
parameter passed in before starting.