使用 setViewControllers 时 UINavigationController 导致应用程序崩溃
我的 UINavigationController 有一个奇怪的问题。
我编写了一个应用程序来显示三个级别的数据。 (根视图:选择数据 I,第二个视图:选择数据 II,第三个视图:显示数据)。这很好用,没有问题。
当 PushMessage 到达时就会出现问题:在这种情况下,我尝试使用 UInavigationController 的 setViewControllers:animated: 方法手动创建一个 viewController Stack:
我正在初始化三个视图控制器(带有数据、标题等)并且将它们添加到数组中。 该数组被传递给提到的方法(setViewCOntrollers),并且顶部ViewController的视图正确显示。 但是当用户触摸左上角的后退按钮时,应用程序崩溃了。这个Button的Title是堆栈中前一个ViewController的Title,所以堆栈看起来是正确的。 仅当收到推送通知(即调用 setViewControllers 方法)时显示 rootViewController 的 View 时,才会发生此错误。
我的代码:
EMASubstituteTeacherScheduleAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
UINavigationController *navController = [appDelegate viewController];
MainViewController *main = [[MainViewController alloc] initWithNibName: @"MainViewController" bundle: nil];
main.navigationItem.title = @"Test";
FormViewController *formSelect = [[FormViewController alloc] initWithNibName: @"FormViewController" bundle: nil];
formSelect.navigationItem.title = @"Test (Level 2)";
formSelect.substDate = [pushData objectForKey: @"date"];
SubstitutesViewController *substDisplay = [[SubstitutesViewController alloc] initWithNibName: @"SubstitutesViewController" bundle: nil];
substDisplay.navigationItem.title = @"Test (Top)";
substDisplay.substDate = [pushData objectForKey: @"date"];
substDisplay.substForm = [pushData objectForKey: @"form"];
NSArray *controllers = [[NSArray alloc] initWithObjects: main, formSelect, substDisplay, nil];
[navController setViewControllers: controllers animated:YES];
控制台上显示的消息: 程序收到信号:“EXC_BAD_ACCESS”。
调用堆栈:
'#0 0x3433886c in objc_msgSend'
'#1 0x3061a828 in -[UIApplication sendAction:to:from:forEvent:]
'#2 0x3061a7c8 in -[UIApplication sendAction:toTarget:fromSender:forEvent:]
'#3 0x3061a79a in -[UIControl sendAction:to:forEvent:]
'#4 0x3061a4ec in -[UIControl(Internal) _sendActionsForEvents:withEvent:]
'#5 0x3061ab3a in -[UIControl touchesEnded:withEvent:]
'#6 0x306194ec in -[UIWindow _sendTouchesForEvent:]
'#7 0x30618e66 in -[UIWindow sendEvent:]
'#8 0x30614b5a in -[UIApplication sendEvent:]
'#9 0x30614506 in _UIApplicationHandleEvent
'#10 0x3323a146 in PurpleEventCallback
'#11 0x3293daaa in __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__
'#12 0x3293f84e in __CFRunLoopDoSource1
'#13 0x3294062c in __CFRunLoopRun
'#14 0x328e98ea in CFRunLoopRunSpecific
'#15 0x328e97f2 in CFRunLoopRunInMode
'#16 0x332396ee in GSEventRunModal
'#17 0x3323979a in GSEventRun
'#18 0x305be2a6 in -[UIApplication _run]
'#19 0x305bce16 in UIApplicationMain
'#20 0x00002512 in main at main.m:14
提前致谢!
I have a strange problem with the UINavigationController.
I wrote an App to display data in three levels. (RootView: Select Data I, Second View: Select Data II, Third View: Display Data). This works great, no problems.
The problem appears when a PushMessage arrives: In this case I'm trying to create a viewController Stack manually, using the method setViewControllers: animated: of the UInavigationController:
I'm initializing the three view Controllers (with Data, title, etc) and adding them to an array.
This array is passed to the mentioned method (setViewCOntrollers), and the view of the top ViewController is displayed correctly.
But when a user touches the Back Button at the top left, the app crashed. The Title of this Button is the Title of the previous ViewController in the stack, so the stack seems to be correct.
This error happens only if the rootViewController's View is displayed when receiving the Push Notification (which means calling the setViewControllers method).
My Code:
EMASubstituteTeacherScheduleAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
UINavigationController *navController = [appDelegate viewController];
MainViewController *main = [[MainViewController alloc] initWithNibName: @"MainViewController" bundle: nil];
main.navigationItem.title = @"Test";
FormViewController *formSelect = [[FormViewController alloc] initWithNibName: @"FormViewController" bundle: nil];
formSelect.navigationItem.title = @"Test (Level 2)";
formSelect.substDate = [pushData objectForKey: @"date"];
SubstitutesViewController *substDisplay = [[SubstitutesViewController alloc] initWithNibName: @"SubstitutesViewController" bundle: nil];
substDisplay.navigationItem.title = @"Test (Top)";
substDisplay.substDate = [pushData objectForKey: @"date"];
substDisplay.substForm = [pushData objectForKey: @"form"];
NSArray *controllers = [[NSArray alloc] initWithObjects: main, formSelect, substDisplay, nil];
[navController setViewControllers: controllers animated:YES];
Message shown at the console:
Program received signal: “EXC_BAD_ACCESS”.
Call Stack:
'#0 0x3433886c in objc_msgSend'
'#1 0x3061a828 in -[UIApplication sendAction:to:from:forEvent:]
'#2 0x3061a7c8 in -[UIApplication sendAction:toTarget:fromSender:forEvent:]
'#3 0x3061a79a in -[UIControl sendAction:to:forEvent:]
'#4 0x3061a4ec in -[UIControl(Internal) _sendActionsForEvents:withEvent:]
'#5 0x3061ab3a in -[UIControl touchesEnded:withEvent:]
'#6 0x306194ec in -[UIWindow _sendTouchesForEvent:]
'#7 0x30618e66 in -[UIWindow sendEvent:]
'#8 0x30614b5a in -[UIApplication sendEvent:]
'#9 0x30614506 in _UIApplicationHandleEvent
'#10 0x3323a146 in PurpleEventCallback
'#11 0x3293daaa in __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__
'#12 0x3293f84e in __CFRunLoopDoSource1
'#13 0x3294062c in __CFRunLoopRun
'#14 0x328e98ea in CFRunLoopRunSpecific
'#15 0x328e97f2 in CFRunLoopRunInMode
'#16 0x332396ee in GSEventRunModal
'#17 0x3323979a in GSEventRun
'#18 0x305be2a6 in -[UIApplication _run]
'#19 0x305bce16 in UIApplicationMain
'#20 0x00002512 in main at main.m:14
Thanks in advance!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我假设您在主线程中进行用户界面更新。
有一次,当我尝试将视图控制器从一个导航堆栈放到另一个导航堆栈时,导航发生了崩溃。看来我试图设置到另一个导航堆栈的视图控制器当前不能有父级。
当推送通知进来时,你的MainViewController是navigationController的rootViewController吗?如果是这种情况,当您尝试手动将 MainViewController 放入导航堆栈时,框架可能会不喜欢它。在放入数组中设置 viewController 之前,您可能需要先从导航堆栈中删除 mainViewController。一种解决方法是使用一个虚拟 viewController 作为 rootViewController,以便在新的导航堆栈上使用该 viewController 之前,您可以使用 popToRootViewController 轻松地从堆栈中删除实际的根 ViewController。
这是我从你的问题中想到的一个想法。您的情况可能与我遇到的情况相同,也可能不同。
I assume you do your User Interface updates in the main thread.
One time I had a crash on navigation when I tried to put a view controller from one navigation stack to another navigation stack. It seems that the view controller, that I am trying to set to another a navigation stack, cannot currently have a parent.
Is your MainViewController the rootViewController of navigationController when the push notification comes in? If that is the case, the framework might not like it when you try to put the MainViewController to the navigation stack manually. You might need to remove the mainViewController from the navigation stack first before you put into the array to set viewControllers. One workaround would be to have a dummy viewController as rootViewController so that you can easily remove your actual root ViewController from the stack using popToRootViewController before you use that viewController on a new navigation stack.
It is a thought that comes to me from your question. Your case might or might not be the same as what I encountered.
有同样的问题,用这个解决了:
Have the same issue, solved it with this: