What mechanism checks the code for potential bugs? - iphone

If I put any code (eternal cycle like while(1) or sleep(xxxxx)) that potentially can hang out main thread:
- (void)viewDidLoad
{
[super viewDidLoad];
while (1) {
}
//[NSThread sleepForTimeInterval:10000];
}
I'm getting SIGABORT just after launch in approximately 50% of launches.
What is going on?
Though, if program is launched it is never (for at least 10 minutes) terminated as it should according to Synchronous Networking On The Main Thread. What about watchdog that should check application responsiveness and terminate the one that got stuck?
I presume that there's a question about this here but it doesn't contain meaningful answer though.
Tested both on simulator and device. The startup crash appears only on sim. Though the program is terminated neither on device nor on sim.
So there are actually two questions:
1. What about watchdog?
2. What is this startup crash on sim?
P.S. Sorry for my English I hope you've got what I mean.You're welcome to edit my post.

If your application is crashing then look at the code with the debugger. Add break point exceptions to the first view's -(void)viewDidLoad method as a starting point and see where it crashes. This normally exposes bugs quickly.
I suggested viewdidLoad as it is called the moment before the view comes to screen. If your very first screen is crashing - I'd start with its' viewDidLoad method.

Related

view seems to reload itself

If I stop using my app for a long time then go back to it, it seems like the viewDidLoad method is being called again, even though I never "exited" the app (by pressing the home key twice and tapping the X) nor did I reboot the iPhone. If I just go to the home screen and then open the app again after a short time this does not happen. What is going on?
This has to do with the way that the operating system manages memory and how it deals with having many different apps open at one time. In a short summary, if your app is in the background for a long period of time, eventually, the OS will decide that it is inactive, and the memory associated with its view will be marked for reuse somewhere else where it is more needed. This is the viewDidUnload method in your view controller. Any time the viewDidUnload method is called, the viewDidLoad method will be called again so that you get a chance to reload your view before the user sees it.
Edit:
You cannot rely on this phenomenon happening every x minutes. It will only happen as the OS requires more memory for active apps. If you want to make sure the user always gets updated information when he or she resumes usage of your app, use NSNotificationCenter and register for the UIApplicationDidBecomeActive notification.
You can try to monitor the memory waring. Most of situation like this is memory warning get trigger and viewDidUnload get called after that if the view is not the top most. So when you back to that view, viewDidLoad will get called again.
You can try to override this method in UIViewController and see if memory warning get called. It maybe triggered by some other component in your application.
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}

iOS - Memory Management: Where is all this memory going?

I've got a fairly basic app that I'm updating - and as part of the update I'm implementing memory warning management.
When the memory warning method gets called, I release any view controllers not in use (and these in turn release any of their objects). Everything seems to work fine, there are no leaks etc as far as I can tell.
What isn't working:
Using the 'allocations' instrument, there is a lot of memory that isn't being released when a simulated hardware warning is called. Here's what I do when testing:
1 - start the app - this is the original jump in memory shown below.
2 - add a new view controller - this is the second spike.
3 - Return to the main view controller and simulate a hardware memory warning - this is the (small) drop in memory towards the end. This warning should completely release the additional view controller and associated objects.
Although everything is released, there is a lot of memory that remains. As far as I can tell, it's something like cached animations etc that iOS does. In a real low memory situation though, this should be released, and not stick around as this is where the majority of the memory goes.
How can this memory be released - or what am I doing wrong? Any pointers would be much appreciated - thanks!
-
EDIT: Thanks for all the answers so far! Although unfortunately I still haven't been able to solve the issue yet. Furthermore, the memory weirdness only seems to occur when using modal view controllers.
I've noticed that I actually have a background loading method for the extra view controller called when the app launches, to make things run smoothly. This indicates that the second spike in memory is completely due to something other that the view controller - maybe animations or something? Anyhow the problem still remains - what is this extra memory being used for, and how do I release it when I need to?
I could potentially create a mini project that exhibits the behavior if it would help. Thanks :)
Are you really sure you are not retaining your UIViewController or its objects? You shouldn't have to simulate a memory warning to see a decrease in allocations after releasing your controllers.
I attached a screenshot showing how my application looks after pushing and popping a UIViewController three times, using a UINavigationController.
EDIT
To answer your comments: UIViewController belongs to UIKit and is not thread safe, which means you should not be creating one in a background thread. This could potentially be the cause of the memory leak, since it will not be added to the main autorelease pool.
There's a really-really great screencast about memory analysis with Instruments from WWDC 2010. That's how I learned how to track similar issues.
You should check out http://developer.apple.com/videos/wwdc/2010/. To be specific http://developer.apple.com/videos/wwdc/2010/?id=311.

iPhone. Shouldn't hitting the home button cause UIApplicationDelegate's dealloc to be called

I have put NSLogs in all my classes including my UIApplicationDelegate subclass. I am curious - and a bit nervous - about why I am not seeing them echo anything when I press the home button. I am running in the XCode simulator.
Since iPhone/iPad runs a single app at a time, doesn't hitting the home button discard all traces of the running app?
Thanks,
Doug
Chuck is correct, the dealloc's don't matter at that point. If you want to do something as your app is expiring, implement this in your app delegate class:
- (void)applicationWillTerminate:(UIApplication *)application {
// goodbye...
}
When an app is terminated, its memory is simply freed. Dealloc is not called, it does not pass go or collect $200. This is normal and intended.
You should implement -(void)applicationWillTerminate:(UIApplication*)application{
}
this method will get called when user hit home button.
You might also want to think about the additional multitasking support that has been announced. Obviously the details are still under NDA, but pushing Home does not necessarily stop your app.
And think about the various circumstances where your app may already be terminated quickly (e.g. if a call comes in and the system runs out of RAM). Do your cleanup with the application lifecycle messages.

iPhone app stop rotating after few touches or sometimes stop rotating at all, other times works just fine. Any idea where to look for the problem?

iPhone app stop rotating after few touches or sometimes stop rotating at all, other times works just fine. Any idea where to look for the problem?
My app is designed to support auto-rotate and works fine previously until I added some code that move JSOn data loading to another thread.
Are you trying to do the rotation through the other thread? If this is the case then the you must make those calls on the main thread. UIKit is not thread safe, anything not done on the main thread is not guaranteed. What you must do is call performSelectorOnMainTHread NSObject method in order to get the behavior that you are expecting
are you calling
[[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications];
anywhere in your code? if not, I agree with the previous answer that you must just be confusing UIKit somehow.

Crash At Splash Screen, iPhone

I have an app which when opened, displays a splash/loading screen. I had this set at 2.5 seconds before the app moved on.
- (void)applicationDidFinishLaunching:(UIApplication *)application
{
sleep(2.5);
[window addSubview:viewController.view];
[window makeKeyAndVisible];
}
I now want the app to pause at the splash screen for a minute (there is a very good reason for this) so I thought:
sleep(60.0);
could be used. When I use this though, my app opens and stays at the splash screen for about 20 seconds, before quitting/crashing back to the springboard.
Any idea why this is the case?
How should I do this?
Edit // It is worth noting both:
sleep(15.0);
and
sleep(19.0);
work.
sleep(20.0);
does not.
Solution // Do not use sleep, use timer. I followed tutorial here:
http://adeem.me/blog/2009/06/22/creating-splash-screen-tutorial-for-iphone/
Many thanks,
Stu
I'm purely guessing here, but it may be that, because you're blocking the main thread (using sleep instead of a timer), the iPhone OS is seeing that as an "unresponsive app" and killing it.
Check out NSTimer.
I agree with Joshua Nozzi, that the OS "thinks" that your app has crashed.
I'd remove the sleep() and do this instead:
[window performSelector:#selector(addSubview:) withObject:viewController.view afterDelay:60.0f];
[window performSelector:#selector(makeKeyAndVisible) withObject:nil afterDelay:60.0f];
If you look in your console you will probably see something like the following...
Warning: your application name failed to launch in time
Warning: Forcing crash report of your application name...
Warning: Finished crash reporting.
Basically, because you've put the main thread to sleep for too long the OS decides that the application failed to launch and forces the app to exit. You would be better of using a timer to do the delay so that the main thread remains active.
I would suggest you implement the Splash screen logic differently than the current cruel one :)
perhaps, you could create a UIView covers the whole screen, upon touch or after a timeout, self destructs (removeFromSuperview)??
Um, there is never a good reason for sleeping an iPhone app for 60s. Never. May your app in its current form never reach the App Store! :)
Have a look at this blog entry that describes how to create a splash screen that will fade out and you should be able to set the delay time for how log it will be visible. Look where the timer is created.
http://icodeblog.com/2009/03/18/iphone-game-programming-tutorial-part-3-splash-screen/
[NSThread sleepForTimeInterval:0.85];
I think u can use this method.