UIAlertView and memory leak - objective-c

UIAlertView* av = [UIAlertView alloc];
int a = [self somefunc];
if (a == 1)
{
[[av initWithTitle:nil message:#"test msg 1" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil] show];
}
else if (a == 2)
{
[[av initWithTitle:nil message:#"test msg 2" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil] show];
}
[av release];
when I run anlyze on this code i am getting the error "refence counted object is used after it is released" at line [av release];
can I know, where av got released, does show function of UIAlertView released av?
strangly the below code doesnt show any error when analyze tool is used
if (a == 1)
{
UIAlertView* av = [[UIAlertView alloc] initWithTitle:nil message:#"test msg 1" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[av show];
[av release];
}
else if (a == 2)
{
UIAlertView* av = [[UIAlertView alloc] initWithTitle:nil message:#"test msg 1" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[av show];
[av release];
}

You must always use the return value of any init call, because an init function can return a different value. Therefore, if you really want to separate alloc and init then you have to do it like this:
UIAlertView *av = [UIAlertView alloc];
// ...
av = [av initWithTitle:...]; // Might change the value of av !!
[av show];
[av release];
The "spurious release" in your code happens here:
[av initWithTitle:...]
because that might (as explained above) release av and return a different object.

In your first code the object "av" is not sure to be initialized, what if the value of a is not 1 0r 2? av will not be initialized so when your release it there will be some problems.
In your second code av's scope became more specific or local to the conditions of if and else. Thats why xcode is sure that av will be initialized and it is safe to relese av.

show function is not releasing the UIAlertView if it is the question here (in the second code).

Related

Xcode 11.2.1 "Expected :" error in code segment when running build

I am using Xcode 11.2.1 and I am getting a parse error of Expected ':'.
The section of code is:
-(IBAction)webview:(id)sender {
if ([Web isEqualToString:#"Not Available"]){
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"This airport does not have a Web site." message:Web delegate:self cancelButtonTitle:#"Close",nil otherButtonTitles:nil];
[alert show];
[alert release];
} else {
AirportWebViewController *web = [[AirportWebViewController alloc] initWithNibName:#"AirportWebViewController" bundle:nil];
[web setTitle:#"Selected airport"];
[web setWeb:self.Web];
[self.navigationController pushViewController:web animated:YES];
}
}
Where have I missed the placement of the ":"?
cancelButtonTitle:#"Close",nil otherButtonTitles contains an extra nil, it should be
cancelButtonTitle:#"Close" otherButtonTitles

UIAlertView alertView.cancelButtonIndex = -1; Not Working

I am trying to create an AlertView which does not have a cancel button.
This is the code I have tried:
alertView.cancelButtonIndex = -1;
It does not seem to work with iOS 7.
Any ideas?
Thanks,
1) With using this code pressing "Do something button" can do some action but will not lead to alertView hiding
UIAlertView *alert = [[[UIAlertView alloc] initWithTitle:#"Title" message:#"The message." delegate:self cancelButtonTitle:nil otherButtonTitles: #"Do something", nil] show];
#pragma mark - UIAlertViewDelegate
- (BOOL)alertViewShouldEnableFirstOtherButton:(UIAlertView *)alertView {
return NO;
}
2) With using this code there will be no buttons on the alertView(I think this is what you actually need)
UIAlertView *alert = [[[UIAlertView alloc] initWithTitle:#"Title" message:#"The message." delegate:self cancelButtonTitle:nil otherButtonTitles:nil] show];

UIAlertView and releasing object after showing it

I am reviewing some source code and noticed this method below. It isn't releasing the message after allocating it. Shouldn't there be a [message release]; after the show?
- (void)service:(TestService*)service didFailWithError:(NSObject *)error
{
UIAlertView *message = [[UIAlertView alloc] initWithTitle:#"Service Error"
message:errorMsg
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[message show];
}
If ARC wasn't enabled, then yes, release should have been called after show.

How can I make it so only 1 "if-statement" is used if 2 are in the action

In a game...
When the "done" button is pressed, there are 2 'if-statements': one brings you to the next level and the other returns you home. How can I make it so only one happens at a time? The way it works now, is both the winning and losing 'alertviews' pop up no matter if the user got it right or wrong. This is how it looks:
-(IBAction)done {
if ([entry.text isEqualToString:sentance.text]) {
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:#"Cleared!"
message:#""
delegate:nil
cancelButtonTitle:#"Ok"
otherButtonTitles: nil];
[alert show];
[alert release];
seconds.text = #"5 Seconds";
}
if ([entry.text isEqualToString:entry.text]) {
NSString *nssScore= [NSString stringWithFormat:#"Final Score: \n %i Points", Score];
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:#"Nope! Wrong"
message:nssScore
delegate:nil
cancelButtonTitle:#"Ok"
otherButtonTitles: nil];
[alert show];
[alert release];
}
}
There is something wrong with your second if.
if ([entry.text isEqualToString:entry.text]) {
This if is always true, since why should entry.text not be equal to itself?
Also if you have two if statements and only one shall be true, you always use a else if for the second one:
if (<condition>) {
} else if (<other condition>) {
}
If condition is true, the other if is not executed, even if other condition is also true. However, in your case your second if seems nonsense to me. An if that is always true is useless and be left out completely. The code is equivalent to
if (<condition>) {
} else {
}
You can use else if condition.
Like this :
-(IBAction)done {
if ([entry.text isEqualToString:sentance.text]) {
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:#"Cleared!"
message:#""
delegate:nil
cancelButtonTitle:#"Ok"
otherButtonTitles: nil];
[alert show];
[alert release];
seconds.text = #"5 Seconds";
}
else if ([entry.text isEqualToString:entry.text]) {
NSString *nssScore= [NSString stringWithFormat:#"Final Score: \n %i Points", Score];
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:#"Nope! Wrong"
message:nssScore
delegate:nil
cancelButtonTitle:#"Ok"
otherButtonTitles: nil];
[alert show];
[alert release];
}
}
or you can add a line of code in each block "return;"
like this:
I got the answer guys...
if ([a.text isEqualToString:b.text] == FALSE) {
condition
}
Thanks!

Alert View in the Beginning and the End of a void

I have a Void. This void do something really slow, so at the beginning of Void I put an alert, and in the end I put another warning. Like here:
-(void)action {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Start" message:#"Start." delegate:self cancelButtonTitle:#"Ok." otherButtonTitles:nil];
[alerta show];
[alert release];
//Something really slow
UIAlertView *alertEnd = [[UIAlertView alloc] initWithTitle:#"End" message:#"End." delegate:self cancelButtonTitle:#"Ok." otherButtonTitles:nil];
[alertEnd show];
[alertEnd release];
}
But when I run this code, the alerts are only shown at the end of the Void, after all the slow action.
How can I fix this?
First of all: try to avoid using many alerts since it's not humane to you users. Show UIActivityIndicator instead.
If you must, then try this code for showing the first alert:
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Start" message:#"Start." delegate:self cancelButtonTitle:#"Ok." otherButtonTitles:nil];
[alert performSelector: #selector(show)
onThread: [NSThread mainThread]
withObject: nil
waitUntilDone: NO];
you will have to separate the two in two methods and then call one using
[self performSelector: afterDelay:]
method