UIAlertView memory issues - iphone

I have created a very simple iPhone application, with single view and a UIButton with action to show UIAlertView.
I am using following code
- (IBAction)showAlert:(id)sender {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error" message:#"Message" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alert show];
[alert release];
}
Instruments allocations tool screen shot is attached.
In the image,low memory allocations shows app running without showing UIAlertView, and high peaks shows memory usage after i have shown UIAlertView, even i have dismissed UIAlertView and release it but it continues to show same memory state and living objects (as high as 50,000). but when i press home button app goes in background and you can see in attached image living objects and used memory decrease.
Questions:
Whats wrong with my code?
Why even after releasing UIAlertView it shows high memory allocation and living objects?
Why i have to go to background to release memory and living objects?

I would not worry too much about it, unless this is the major memory bottleneck in your app, or unless each UIAlertView cumulatively adds more memory.
Your code is correct. But even though you release the UIAlertView, the user interface system holds on to it at least until you dismiss the alert. In addition to the UIAlertView itself, it also allocates graphics resources needed to show the alert. After you dismiss the alert, it depends on when the autorelease loop kicks in, and on caching parameters, whether and when the memory gets released.
When you push the home button, then your application goes to the background, and as part of that memory deallocation is forced. That is, caches are emptied, autorelease cycle is run, etc.

Related

Cleaning all memory leaks in ios

I have tried a lot to stop all leaks from my app. But when I am syncing large amount of data from
server then my ios application leaking memory.
Now I want to clean all leaked memory after some time of interval or you can say whenever i get call in function.
-(void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
UIAlertView* alertobj = [[UIAlertView alloc] initWithTitle:#"Info" message:#"This Application facing memory issue." delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alertobj show];
NSLog(#"memory issue occur");
// Dispose of any resources that can be recreated.
}
Is there any way??
Nope, you can't do that.
I ran into a similar issue, sync data in smaller chunks and read about #autoreleasepool
Basically I sync between 500~1500 objects at a time depending on how much data is in the objects, wrapping them in the #autoreleasepool keeps memory low by getting rid of those objects as soon as I am done with them.

Obj-C, thread safe process with alertview / progress indication in a view, can be called from applicationWillEnterForeground <= iOS4?

I need to run some database processing when my app first starts once a day.
I elected to do this in my first view and showed an alertview with an activity indicator. I tried using NSThread detachNewThreadSelector to run the db processing. At the end of the function I used dismissWithClickedButtonIndex to dismiss the alert view.
I then called the view controller from applicationWillEnterForeground if the date permitted.
However, I'm getting an error Tried to obtain the web lock from a thread other than the main thread or the web thread. Crashing now, on the dismissWithClickedButtonIndex line.
I believe this is occurring due to a flaw in using an object like an alertview with a thread.
I need this to be iOS 4 compatible.
Can anyone point me at an alternative approach ?
You won't be able to create and work directly with the UIAlertView in a background thread.
Here's a skeletal idea of what you could do:
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Title" message:#"Message" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
// create your progress indicator in your alert view
[alertView show];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// do your db update
dispatch_async(dispatch_get_main_queue(), ^{
// update your alert view here.
});
});
The idea is to do your processing on a background queue and message back to the main queue for objects that are main-thread only (like UIAlertView.)

applicationWillTerminate problem

I want to show the UIAlertView when user Click the Iphone Home button( means Close the application)
I have done these Code
- (void)applicationWillTerminate:(UIApplication *)application
{
NSString *errorString =#"Testing";
UIAlertView * errorAlert = [[UIAlertView alloc] initWithTitle:#"Alert" message:errorString delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[errorAlert show];
[errorAlert release];
}
But UIAlertView is not Showing. please help
Thanks in Advance
The user aims to close your app when he/she presses the home button. Apple suggest to let him/her to that. What I want to say: Don't do that. I think it is even not possible.
Look at Problem with applicationShouldTerminate on iPhone:
The alert view is never shown because
the 'show' method does not block, and
therefore, the end of
'applicationWillTerminate' is reached
immediately after you create the
alert view and try to show it. I
believe this is by design. You can't
really begin asynchronous operations
in 'applicationWillTerminate'.
applicationWillTerminate: may not be called in the newer version of iOS when pressing the Home button because the app could be only entering the background mode, not actually terminating.
Even if it is actually called (either the app is really terminated, or you're moving the code to applicationWillEnterForeground:), showing the alert is useless because the alert is associated with the active app, and your app has gone inactive by the time the alert is shown! So what happened really is, the alert is gone when the user press the home button, and when they resume your app, they see a mysterious alert popping up.
Don't ask if the user wants to quit your app. This isn't the norm in iOS. Instead, save all states in applicationDidEnterBackground:, and restore them in applicationWillEnterForeground: and application:didFinishLaunchingWithOptions:, making the user feel as if the app has never been terminated.
You might not want to use applicationWillTerminate but rather applicationWillResignActive. Check older posts like this one for more info.
You can't show a uialertview when application receive SIGKILL(Exit) Command.You can call any file or background functions in applicationWillTerminate - To do that you need to set a key in your plist.
UIApplicationExitsOnSuspend - Boolean - YES.

iPhone Memory Alert

I have read about this function didReceiveMemoryWarning that actually hasn't really helped.
I would like to show a UIAlert View to tell the user that the action he is about to take will lead to problems with memory.
So apart from crashing, which is a nasty way to inform the user that there is a memory Warning received, is there a possible implementation of a UIAlertView?
In your application delegate class (eg MyApplicationAppDelegate.m) implement the didReceiveMemoryWarning method:
- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application
{
// Show an alert
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Warning"
message:#"Running low on memory"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
[alert release];
}
Pheelicks did give you a good answer to your question, but this is definetly not what you want to do. When you receive this warning, you are already in low memory condition. What you want to do when you receive this warning is release as much memory as possible. Like large images that you might be keeping in memory, large arrays of string or any other large object. Instruments will help you alot in finding the culprits.
Also, you also want to implement didReceiveMemoryWarning on any view controller that allocates alot of memory so they can do some cleanin up there also
Hopes this helps :)
the action he is about to take will
lead to problems with memory
If there is some action you know of the user taking that will lead to memory problems, you should keep them from taking that action, or just warn them yourself when they are about to take the action (with an alertview).

Bug in AlertView on iPhone?

I write a piece of code to "do something->show alert1->do something->show alert2".
//do something
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:#"Alert 1"
message:nil
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
[alert release];
//do something
UIAlertView *alert2 = [[UIAlertView alloc]
initWithTitle:#"Alert 2"
message:nil
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert2 show];
[alert2 release];
And suddenly a strange thing happened to multiple AlertViews: It shows "Alert 1"->"Alert 2"(Press 'OK')->"Alert 1". Why "Alert 1" shows again? I haven't written any delegate method yet. Maybe a bug?(Thanks to cobbal, alert1 is still there when alert2 appears.)
I find -(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex works well. Is the delegate method a common way to show multiple alertViews?
I would guess that alert 1 is shown and then covered by alert 2 since show isn't modal. When alert 2 is closed, alert 1 is still open.
To your second question, alertView:didDismissWithButtonIndex: may work better, but I haven't actually tested that.
The delegate is so that you can be notified when the alert is dismissed, and which button was used to dismiss it. It doesn't impact whether the alert is dismissed at all.
The alert will remain visible until it is dismissed either by you tapping a button (if any - they are not required) or you call either [UIAlertView dismissWithClickedButtonIndex:animated] or the (undocumented) dismiss method of the alert instance.
It looks like (as Cobbal suggested), alert 2 is popping up over alert 1, you dismiss alert 2, and alert 1 remains there (until it itself is dismissed).
Is there a particular reason you want to show a new alert while another is still showing? Perhaps some more context would help us to get to the root of the issue, which I suspect may be a design issue.
[edit] coming back to this and reading again, I wonder if what you are asking about with the delegate method is whether you should be showing alert 2 from there? In which case that's probably what you want - whether directly or indirectly. By indirectly I mean that you may have some state set elsewhere that determines whether alert 2 should be shown (or the circumstances that lead to it). That state (a flag, perhaps) could be set when you show the first alert, and cleared when the alert is dismissed (from the delegate method).
The reason this happens is because UIAlertView doesn't block while it's showing. Any code written after showing an alertview will run straight after the alert is shown.
What you should have is two different methods. One that does something and then shows an alert, and then another that does something and shows another alert.
Kick off the first method to do something and show an alert, and then hook into the alert's delegate method, and when you get the callback from the alertview, run the other method.
This way, the second part of the process won't happen until the user has pressed OK on the alert in first part of the process.