My top level view immediately Pushes my SplashView in it's ViewWillAppear method. In some conditions, the SplashView pushes an additional view, which is properly popped. When this occurs the Top Level view never appears.
However, the code in the Top Level is running (it has a timer that occurs every minute which writes to the log). And if I trap it in Debug I can see the code executing. Additionally, in the Top Level ViewDidAppear if I log the [self navigationController].visibleViewController.nibName the name of the Top Level appears.
If I don't do the Push in the SplashView everything works fine.
The app is forced into Landscape mode, and each ViewController contains return UIInterfaceOrientationIsLandscape(interfaceOrientation); for the shouldAutorotateToInterfaceOrientation method.
I'm baffled and don't know what to do next. Suggestions?
While I did not exactly determine why this was occurring, I have resolved the problem. Here are some things I noticed in further debugging:
I noticed the message wait_fences: failed to receive reply: 10004003 in the log. Scanning blogs on this didn't help me much, but it led further down the path. References to it showed issues with UIAlertView, which I did have in the Splash view.
I added ViewDidAppear logic to the Splash view, then found this was getting called twice! I then added logic to act on this only once and my problem was solved!
So apparently there is some quirk with the View getting called twice that was creating my initial issue. References I found implied this was an 'old' OS issue, but I am using xCode 3.2.3 and SDK 4.0.2, so maybe it's back! Gee, I don't recall it doing this with SDK 4.0.1!
Related
I made a universal application that contains NIB files for both ipad and iphone UI's. In my view controllers initWithNibName method I call UIUserInterfaceIdiomPad == UI_USER_INTERFACE_IDIOM() to detect whether the controller is running on iphone or ipad.
I then launch their respective nib files. When I run the app on iphone, it works fine, but when I run it on ipad it eventually crashes with a EXC_BAD_ACCESS error. This error occurs when I use a view controller to launch another view controller, which then launches another one in the navigation stack. This error occurs as soon as I click the view that belongs to the third controller of the stack.
I cannot distinguish a difference between the NIB files that would cause a crash. I have been working tirelessly to figure out why this is happening but I cannot fix this error. Does anyone have any insight into what might be going on?
Any advice on how to approach fixing this problem would be very appreciated.
The first thing you should do is enable the "All Exceptions" break point. This will often accurately tell you the line of code where the EXC_BAD_ACCESS is happening.
Next, I would turn on zombies and see where the over-release is happening. To do so, in Xcode, while holding the option key, click Product | Run.... In the ensuing window, add NSZombieEnabled to the environment variables list.
Then run. Do the normal things you do to cause the crash and see where the debugger lands. With any luck, it will stop where the problem is actually occurring.
When you get a EXC_BAD_ACCESS it means you're trying to access/release something that's already been released. If you're in a non-ARC situation, it normally means you've inadvertently released something when you didn't mean to, so just check for alloc/init and release balance. If, however, you're in an ARC situation, I would bet it has to do with not niling a delegate when a view controller gets released.
For example, if you have a MKMapView and have set its delegate to your view controller, you should nil its delegate when your view gets unloaded or dealloc'd. Otherwise, messages will continue to get set to it. Or, another possibility is that you've added your view controller as an NSNotificationCenter observer and didn't remove it as an observer when the view controller was unloaded or dealloc'd.
Another possibility is that you're re-using view controllers between the two versions of your universal app. If you are accessing anything by an identifier that doesn't exist in the nib for the iPad, that would cause a crash--though if you're using nibs as opposed to storyboards, that may not be an issue.
That's about all I can think of for now. Try to zero in on where it's happening and post code here if you still can't figure it out.
Best regards.
In my project I show an Alert to the user to indicate an 'empty list'.
Right now, I show it in AppDelegate>applicationDidBecomeActive.
I'm doing this because I want the alert to show if the list is empty
at app startup and when coming out of the background (iOS 4.2 through 5.x).
EDIT:
I use a method in the AppDelegate, and call it with a slight delay, and I still get this notice.
[self performSelector:#selector(checkForNoMessages) withObject:nil afterDelay:1.0];
However, this causes a "wait_fences" notice in the debugger and I'd prefer not to submit to Apple with this notice.
Where is the proper place to put a popup Alert so that it appears:
1) At App startup
AND
2) When the App is coming out of the background?
Do I need the Alert in more than one place?
I recommend writing a method in your AppDelegate or better in your root view controller which shows the message. Maybe with some arguments, so you can reuse it but that's up to you.
If you are following the MVC architecture ask your model about existing entries and trigger the Alert message if necessary. But encapsulate this behavior in a controller as well.
application:didFinishLaunchingWithOptions: and applicationDidBecomeActive: are the places where you want to delegate this task to your controller.
More about iOS Multitasking: https://developer.apple.com/library/ios/#documentation/iphone/conceptual/iphoneosprogrammingguide/ManagingYourApplicationsFlow/ManagingYourApplicationsFlow.html
Edit:
Don't forget that you have to call the methods from the main thread.
And do all startup stuff first.
OK - the problem wasn't where I called the alert, it was because it was in a method. Once I moved the code from a method into applicationDidBecomeActive, all is well.
After some research on the web without success, I come here to ask you the question about my warning.
Actually, I have a view V1 with a navigation controller and I want to push a modal view V2 when V1 has finished loading.
So I use the performSegueWithIdentifier method (I'm using storyboard).
Here is my code:
[self performSegueWithIdentifier:#"showConnexionViewSegue" sender:self];
And when I compile, I got this warning:
Unbalanced calls to begin/end appearance transitions for <UINavigationController: 0x6849b30>
Can anyone help me?
It sounds like you may be performing the segue in -viewWillAppear: thus generating two -viewWillAppear: messages without 2 corresponding -viewDidAppear messages.
Try performing the segue in -viewDidAppear.
I had this problem, but what I had done is on a UIViewController I had linked a Segue from a UIButton and also coded it into a nextBtnPressed: function, so I was actually pushing two new UIViewControllers on the one button press. Limiting it to just the one segue fixed it. But it took some investigating to see that I had done this double up.
'Unbalanced calls to begin/end appearance transitions for '
Says an animation is started before the last related animation isnt done.
So, are you popping any view controller before pushing the new one ?
Or may be popping to root ? if yes try doing so without animation
i.e. [self.navigationController popToRootViewControllerAnimated:NO];
And see if this resolves the issue, In my case this did the trick.
The reasons for this are manifold and are very specific to the context and the programming. For example, what I was doing was
initialising a sound file, playing it (asynchronously) for 1.4 seconds,
making an image move across the screen using animation timed to last 1.4 seconds and,
with a timer set to 1.4 seconds after step 2, pushing a viewcontroller.
What i discovered is that if I DO NOT have the instructions for these 3 steps one after the other (if I mix them up), then I get the error "Unbalanced calls...". Also, if I time the push of the viewcontroller to less than 1.4 seconds, I get the message as well.
So, check that the sequence and timing of your program instructions are correct.
I have traced a problem in my iPhone app code to the viewDidAppear method not always firing. When you start the app the event fires as expected. However if I close the app using a phone capable of multitasking and reopen in. My viewDidAppear events no longer fire.
My views are loaded from Nibs and I use viewDidUnload to clean up (release and nil all outlets). My views are nested in side and tab bar then navigation controllers. I looks like the events aren't wired up properly when the nibs reload. Any idea on what I'm doing wrong/missing and how I can fix this?
Thanks in advance.
UPDATE I do not mean the event is not fired when the app first comes into the foreground. I mean the event never fires again. Even when changing between tabs or moving though the navigation views.
Example:
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
NSLog(#"viewDidAppear called");
}
This code is placed in two views, each on different tabs. Each time I swap between tabs "viewDidAppear called" is written to the log. When I close and reopen the app and swap between tabs this no longer happens. Other button events fire normally.
Btw, the viewDidUnload method is really badly named btw -- it's not an 'opposite' to viewDidLoad, it's only called if there was a low memory situation and the view for that controller was unloaded due to not being visible at that time.
(ORIGINAL, NOT SO RELEVANT ANSWER:)
Please see my answer to this similar question:
Why does viewWillAppear not get called when an app comes back from the background?
Basically, viewDidAppear gets called after your UIViewController's view was added to the application's UIWindow heirarchy. Backgrounding then restoring the app doesn't change your view in that respect, so viewDidAppear doesn't get called -- it's correct behaviour, and not a bug. Check out the API docs for UIViewController.
Found it.
While not new to programming I am new to iPhone development. On researching this problem I found it was not recommended to call the viewWillAppear and viewWillDisappear methods manually.
My viewWillDisappear methods resign any keyboards if shown, when my app enters the background it loads a splash screen ready for when the app re-enters the foreground (there is some logic I need to do to work out what the user is shown on restarting the app and I can do this under the splash screen).
As viewWillDisappear is not called when the app goes into the background to make sure no keyboards appeared over my splash screen I was calling viewWillDisapper in the applicationDidEnterBackground method. I guess this also un-registers my events.
By adding viewWillAppear to my applicationDidEnterForeground method my events started firing again. Lesson learned, I will refactor this so I don't call these events manually.
Thanks for the help.
I have some code that works fine on my iPod Touch running some 4.0-series iOS as well as the simulator that comes with the iOS SDK 4.1. But when I call [UIViewController dismissModalViewController:] on an iPhone 2 running iOS 3.1.2 it get an infinite recursion, eventually crashing.
I have a view controller that opens a table view where the user selects a document to open. Upon selecting a document my table view controller's delegate calls the parent view controllers dismissModalViewController method. I think it is because I'm closing the view controller whose code is running that causes this.
dismissModalViewController is documented to be available in iOS 2.0 and later.
How can I close the UIViewController that's open from its own code?
I figured my problem might be heap corruption from some previous code. A way to debug that is to comment off snippets of previous code to see whether the bug would go away or come back. Almost immediately I found that I was calling dismissModalViewControllerAnimated: on the current view controller's parent controller. Why that works in iOS 4.x I have no idea. The problem I face is that I have two modal dialogs that I need to close simultaneously, which I cannot get working, but that is a different question.