I am in the Notification Detail screen when I long press on the back button to see History Stack. Main Screen is the root view controller. All the other screens are shown using pushViewController. The issue is for all versions above ios 14
My screen hierarchy is as below:
Main Screen (UINavigationController)
|
V
User Screen (UIViewController)
|
V
Notifications Screen (UIViewController)
|
V
Notifications Detail Screen (UIViewController)
When I try to open the User Screen by selecting the screen from History Stack (long press on the back button), it crashes the app saying:
*** Assertion failure in -[UINavigationController _setViewControllers:transition:animated:operation:], UINavigationController.m:1257
main : *** an exception [UINavigationControllers are not allowed in a navigation controller!
(
0 CoreFoundation 0x00007ff8004288ab __exceptionPreprocess + 242
1 libobjc.A.dylib 0x00007ff80004dba3 objc_exception_throw + 48
2 Foundation 0x00007ff800b870cc _userInfoForFileAndLine + 0
3 UIKitCore 0x000000010c5c1813 __76-[UINavigationController _setViewControllers:transition:animated:operation:]_block_invoke + 255
Related
I have been looking at this for days now and I cannot figure out what is going on.
I have this crash affecting 2% of users per day (across iPad & iPhone, not limited to iOS 12, full stack-trace at the bottom):
Application tried to present modally an active controller <DownloadViewController: 0x10a0c3c00>.
Nowhere in my code do I call UIViewController presentViewController:animated, and there are no modal segues to DownloadViewController. There's always a UINavigationController present (it's the initial VC of the storyboard).
I tried simulating race-conditions where segues are performed twice, or where a UIAlertController is left displayed after the UIViewController under it has disappeared and it attempts to perform a segue to the active VC, but I cannot reproduce this crash: the most I can cause is the DownloadViewController to get pushed onto the UINavigationController twice (not the end of the world and no crash).
This crash started happening after I added some UIAlertControllers so i'm assuming they have something to do with it, but I cannot figure out how.
Any ideas where to go next?
Fatal Exception: NSInvalidArgumentException
0 CoreFoundation 0x2201b0518 __exceptionPreprocess
1 libobjc.A.dylib 0x21f38b9f8 objc_exception_throw
2 UIKitCore 0x24c01859c -[UIViewController _presentViewController:withAnimationController:completion:]
3 UIKitCore 0x24c01aa7c __63-[UIViewController _presentViewController:animated:completion:]_block_invoke
4 UIKitCore 0x24c033570 -[_UIViewControllerTransitionCoordinator _applyBlocks:releaseBlocks:]
5 UIKitCore 0x24c02f930 -[_UIViewControllerTransitionContext _runAlongsideCompletions]
6 UIKitCore 0x24c02f608 -[_UIViewControllerTransitionContext completeTransition:]
7 UIKitCore 0x24ca2ba00 -[UIViewAnimationBlockDelegate _didEndBlockAnimation:finished:context:]
8 UIKitCore 0x24ca02758 -[UIViewAnimationState sendDelegateAnimationDidStop:finished:]
9 UIKitCore 0x24ca02d2c -[UIViewAnimationState animationDidStop:finished:]
10 UIKitCore 0x24ca02dcc -[UIViewAnimationState animationDidStop:finished:]
11 QuartzCore 0x22464f958 CA::Layer::run_animation_callbacks(void*)
12 libdispatch.dylib 0x21fbf17d4 _dispatch_client_callout
13 libdispatch.dylib 0x21fb9f004 _dispatch_main_queue_callback_4CF$VARIANT$mp
14 CoreFoundation 0x220141ec0 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__
15 CoreFoundation 0x22013cdf8 __CFRunLoopRun
16 CoreFoundation 0x22013c354 CFRunLoopRunSpecific
17 GraphicsServices 0x22233c79c GSEventRunModal
18 UIKitCore 0x24c5afb68 UIApplicationMain
19 WeDownload 0x100ea1f40 main (main.m:14)
20 libdyld.dylib 0x21fc028e0 start
Solved it. The issue was that inside a block like this:
[UIView transitionWithView:self.view duration:0.2 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{
... I was effectively calling [self presentViewController:alert animated:YES completion:nil]; twice in a row (where alert was a UIAlertController).
Most important learning: in the error message Application tried to present modally an active controller <DownloadViewController: 0x10a0c3c00>, DownloadViewController is the presenter not the thing being presented. I would have figured this out days sooner if i'd understood that error message correctly.
according to crashlytic someone crash while using the iPad. The crash error they received is -[MFMailComposeInternalViewController _notifyCompositionDidFinish] I don't know how this could've occurred. Here is the exception
Crashed: com.apple.main-thread
EXC_BAD_ACCESS KERN_INVALID_ADDRESS at 0x0000000c
Here is the raw data
Thread : Crashed: com.apple.main-thread
0 libobjc.A.dylib 0x30fa4f46 objc_msgSend + 5
1 MessageUI 0x252e5f01 -[MFMailComposeInternalViewController _notifyCompositionDidFinish] + 464
2 CoreFoundation 0x23524294 __invoking___ + 68
3 CoreFoundation 0x23451435 -[NSInvocation invoke] + 300
4 libdispatch.dylib 0x314f87bb _dispatch_call_block_and_release + 10
5 libdispatch.dylib 0x314f87a7 _dispatch_client_callout + 22
6 libdispatch.dylib 0x314fbfa3 _dispatch_main_queue_callback_4CF + 718
7 CoreFoundation 0x234e59d1 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 8
8 CoreFoundation 0x234e40d1 __CFRunLoopRun + 1512
9 CoreFoundation 0x23432211 CFRunLoopRunSpecific + 476
10 CoreFoundation 0x23432023 CFRunLoopRunInMode + 106
11 GraphicsServices 0x2a7c20a9 GSEventRunModal + 136
12 UIKit 0x26a3e1d1 UIApplicationMain + 1440
13 MyApp 0x0009e7e7 main (main.m:16)
Not sure how I can diagnose it.
This crash happens when MFMailComposeInternalViewController object released and MFMailComposeInternalViewControllerDelegate fired.
Make sure to retain your MFMailComposeInternalViewController object until following delegate fire and then you can safely dismiss the MFMailComposeInternalViewController object.
-(void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error
{
switch (result) {
case MFMailComposeResultCancelled:
break;
case MFMailComposeResultSaved:
break;
case MFMailComposeResultSent:
break;
case MFMailComposeResultFailed:
break;
default:
break;
}
[controller dismissViewControllerAnimated:YES completion:nil];
}
Recently I have faced this crash and have an explanation about this crash.
Consider you have a ViewController and you confirmed the Mail Composer delegate to it. After presenting the Mail Composer, the ViewController get de-initilize (with some reason) and what happened after this is, the Mail Composer try to communicate with the presented view controller that is not exist in the memory.
Im using container view and in UITableViewCell (Each cell having a UIViewController as a child and Im using to clear the cell content when didEndDisplying), here when I present the Mail Composer from My ViewController (It is embedded in UITableViewCell) the didEndDisplay tableView Delegate is getting called because of this my ViewController (embedded in table view cell) is getting removed from the memory, so the confirmed mailComposerDelegates are not there on that time, if I send/Cancel any action on the presented Mail Composer View is giving me the crash.
To fix the issue, I have removed the code (clearing cell content from did end displaying table view delegate method).
To confirm this, please put a break point at deinit() in your view controller where you use to present the MailComposer.
Sorry for my bad English.
Finally fixed this, but mine case was extremely strange.
On iPhone 6s iOS 13.3.1 everything worked perfectly. User could open mail and dismiss it without any problems.
On another iPhone8 also iOS 13.3.1 user couldn't close mail composer - he was stuck with it.
On iPhone 6s iOS 12.4 there was that crash [MFMailComposeInternalViewController _notifyCompositionDidFinish]
Turns out that the reason was two ActionViewControllers that were presented by myViewController just before mail composer was showed by the same myViewController and console output showed:
Warning: Attempt to present <UIAlertController: 0x10c819a00> on <ContactViewController: 0x10d017400> which is already presenting (null)
Somehow it caused class holding MFMailComposeViewController to deinit, but looking at the code it was unrelated to those UIAlertController controllers and still it occurred only on some devices.
So before you present MFMailComposeViewController, make sure that any other view is dismissed before.
Bug info as following:
bool _WebTryThreadLock(bool), 0xf28fbd0: Tried to obtain the web lock from a thread other than the main thread or the web thread. This may be a result of calling to UIKit from a secondary thread. Crashing now...
1 _ZL17_WebTryThreadLockb
2 WebThreadLock
3 -[UIWebTiledView layoutSubviews]
4 -[UIWebDocumentView layoutSubviews]
5 -[UIView(CALayerDelegate) layoutSublayersOfLayer:]
6 -[NSObject performSelector:withObject:]
7 -[CALayer layoutSublayers]
8 CA::Layer::layout_if_needed(CA::Transaction*)
9 CA::Context::commit_transaction(CA::Transaction*)
10 CA::Transaction::commit()
11 CA::Transaction::pop()
12 +[CATransaction commit]
13 FigLayerSynchronizerSynchronizeToMoment
14 itemremote_TimebaseSynchronizationUpdate
15 FigPlayerRemoteCallbacksServer_TimebaseSynchronizationUpdate
16 _XTimebaseSynchronizationUpdate
17 figmoviecallbacks_server
18 fpr_ClientPortCallBack
19 FigExpressNotificationThread
20 figThreadMain
21 _pthread_start
22 thread_start
I know it was caused by updating UI in the thread other than the main thread.But I don't know why it was updated not in the main thread
Following is the description:
It was just similiar to the application BaoFengYingYin. It supported autoplay,minimize playing UI,close Playing UI. When I clicked one picture in picWall,it jumped to a uiviewcontroller A ,and played audio file,show the audio file content and update the progress of progressview.
A was composed by a custom view and a movieplaycontroller variable.
The custom UIView was composed by textview(which show the audio file content),progressView , picture,minimize button ,close button.
As it should continue playing the current audio when I clicked the minimize button ,and when the audio was playing ,I should update the progress of the progressbar in my custom UIView,so I defined the movieplaycontroller variable and custom view as global variable.
The movieplaycontroller variable was initialized in the appdelegate file,But the custom view was initialized in A.
When I clicked minimized button and closed button,I will disappear A,and release the custom view at the same time.
The above is my function need and my implementation. When it enter *A,I didn't created new thread,so I thought the custom view would not be updated by a thread not in the main.But it would crash when I repeatedly clicked different audio to play.It always happened when I repeated several times and not disciplinarian.
It would happen on the iPhone4,I did not see it happen on iPhone4s,iphone 5.I had not iPhone 3gs,so I didnot know if it would happened too.*
Now I modify my code to add the custom view by the function ”performSelectorOnMainThread“ in A's init function.It seemed solved.
I published this question,beacuse I want know the reason caused my custom view updating from a thread other than the main thread.
If someone know,please tell me!Thanks
In the iOS app I am currently working on, the app hits a database to retrieve information every time the page changes. While waiting for the query to execute and the information from the query to populate the fields on the page there is supposed to be a view that popups, animates and says loading. Originally there was a method that checked if there was an internet connection, and if there was would display the popup and then another method would execute the query. These where threaded like so
[NSThread detachNewThreadSelector:#selector(appStartedLoading) toTarget:self withObject:nil];
However this lead to a crash problem about 10% of the time. I don't entirely understand that problem, but I think it was because detaching a new thread like that would sometimes (not always) cause a subview to be added from a thread that's not the main thread. that's kind of a sub question here, wether my theory is logical or not.
Either way we got rid of that method of doing things and just called the methods one at a time without threading. Like this
[self appStartedLoading];
[self performQuery]; //fake placeholder method for examples sake.
But this caused the loading screen to show up after the next page was already display and the query was already executed, presumably because the app was too busy with the query. I've tried running the query in a separate thread the way the subview used to but it did not change it. I've tried running the appStartedLoading method on the main thread and telling it block i.e.
[self performSelectorOnMainThread:#selector(appStartedLoading) withObject:nil waitUntilFinished: YES];
I would think that because it is told to block it wouldn't perform the query till after the subview is added and animating then but it still changes pages first and then displays the loading screen. I've also tried putting little loops in the method to make it not finish till the subview has been added but they finish right away even though the subview does not show up on the screen. The loop is this.
while([[[self.window.subviews objectAtIndex:0] subviews] indexOfObject:loaderView] == NSNotFound)
{
i++;
NSLog(#"this %d", i);
[[self.window.subviews objectAtIndex:0] addSubview:loaderView];
}
It makes sense to me that in only executes once cuz I tell it to add the subview, but why the heck isn't it appearing after adding it? I'm not honestly good at programming yet and very confused by what's going on here, if someone could help shed some light here and point me in the right direction of what's going on behind the scenes that'd be awesome.
here's the error log from crashes
bool _WebTryThreadLock(bool), 0xc8a7fa0: Tried to obtain the web lock from a thread other than the main thread or the web thread. This may be a result of calling to UIKit from a secondary thread. Crashing now...
1 WebThreadLock
2 -[UITextView setFrame:]
3 UIViewCommonInitWithFrame
4 -[UIView initWithCoder:]
5 -[UIScrollView initWithCoder:]
6 -[UITextView initWithCoder:]
7 UINibDecoderDecodeObjectForValue
8 -[UINibDecoder decodeObjectForKey:]
9 -[UIRuntimeConnection initWithCoder:]
10 UINibDecoderDecodeObjectForValue
11 UINibDecoderDecodeObjectForValue
12 -[UINibDecoder decodeObjectForKey:]
13 -[UINib instantiateWithOwner:options:]
14 -[UIViewController _loadViewFromNibNamed:bundle:]
15 -[UIViewController loadView]
16 -[UIViewController view]
17 -[UIViewController contentScrollView]
18 -[UINavigationController _computeAndApplyScrollContentInsetDeltaForViewController:]
19 -[UINavigationController _layoutViewController:]
20 -[UINavigationController _startTransition:fromViewController:toViewController:]
21 -[UINavigationController _startDeferredTransitionIfNeeded]
22 -[UINavigationController __viewWillLayoutSubviews]
23 -[UILayoutContainerView layoutSubviews]
24 -[UIView(CALayerDelegate) layoutSublayersOfLayer:]
25 -[NSObject performSelector:withObject:]
26 -[CALayer layoutSublayers]
27 CA::Layer::layout_if_needed(CA::Transaction*)
28 CA::Context::commit_transaction(CA::Transaction*)
29 CA::Transaction::commit()
30 CA::Transaction::release_thread(void*)
31 _pthread_tsd_cleanup
Try the first way with the background thread and post the log message when and if you can get it to crash. My hunch is that your while loop is spinning off into the blue because you never do actually call break; on that thing. Also, your subview loop approach is way too complicated. If you need something to appear on top of everything else, add it as a subview of the view controller, or better yet, it's navigation controller's view.
This is sort of a mystery to me. My application does not use very much memory but if I put it in the background and run as many memory-intensive applications as I can, occasionally my application will crash when I try to wake it up.
I've looked at the crash log and this is what I see:
0 libobjc.A.dylib 0x000027da objc_msgSend + 18
1 UIKit 0x0008cab4 -[UIViewController unloadViewForced:] + 132
2 UIKit 0x0008ca22 -[UIViewController unloadViewIfReloadable] + 10
3 UIKit 0x0008c9f2 -[UIViewController purgeMemoryForReason:] + 34
4 UIKit 0x0008c896 -[UIViewController didReceiveMemoryWarning] + 10
5 My Application 0x00023340 -[MailboxViewController didReceiveMemoryWarning] (MailboxViewController.m:359)
6 UIKit 0x0008c880 -[UIViewController _didReceiveMemoryWarning:] + 8
As you can I see, my view controller MailboxViewController gets a didReceiveMemoryWarning message. Since that view doesn't have anything memory it can free really, I simply make a call to [super didReceiveMemoryWarning].
The strange thing is that I don't see a call to my view controller's viewDidUnload. It seems to crash with a "EXC_BAD_ACCESS (SIGSEGV)" before it even gets there.
What is going on and how can I fix it?
I guess it crashed at the time your controller unloading its view, so your viewDidUnload never get called. Is your view just some plain view or complex view? My guess is that it might have something to do with your view.
Try debugging with Zombies enabled--it looks like a message is being sent to a deallocated object.