0

I add a function to dismiss the UIAlertView after several seconds.The whole code is like:


- (void)netWorkAlert
{
    UIAlertView *netWork = [[UIAlertView alloc] initWithTitle:@"error" message:@"network has problems" delegate:self cancelButtonTitle:nil otherButtonTitles: nil];
    [netWork show];
    [self performSelector:@selector(dismissAlert:) withObject:netWork afterDelay:2];
}
- (void)dismissAlert:(UIAlertView *)alert
{
    if(alert)
    {
        [alert dismissWithClickedButtonIndex:0 animated:YES];
        [alert release];
    }
}

the netWorkAlert is invoked when the network is unavailable.

Now the problem I met is when the netWorkAlert is invoked at the second time, the app is broken and the Xcode shows error in


int main(int argc, char *argv[])
{
    @autoreleasepool {
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([ZJAppDelegate class]));
//Thread 1 :EXC_BAD_ACCESS(code=1,address=xc0000004)
    }
}

I didn;t use ARC and I don't know why it crashes. Even I comment the [alert release];, it still has the same problem at the second time.

Could anyone help me to check it? thanks!

Ilanchezhian
  • 17,426
  • 1
  • 53
  • 55
scorpiozj
  • 2,687
  • 5
  • 34
  • 60

2 Answers2

1

The EXC_BAD_ACCESS is caused by accessing a released object. To avoid this make your call to UIAlertView kind of modal:

Function body:

-(void)checkSaving
{
    UIAlertView *alert = [[UIAlertView alloc]
        initWithTitle:@"Do you want to add these results to your database?"
        message:@"\n\n"
        delegate:self
        cancelButtonTitle:@"No"
        otherButtonTitles:@"Save", nil];
    alert.alertViewStyle = UIAlertViewStyleDefault;
    [alert show];
    //this prevent the ARC to clean up :
    NSRunLoop *rl = [NSRunLoop currentRunLoop];
    NSDate *d;
    d= (NSDate*)[d init];
    while ([alert isVisible]) {
        [rl runUntilDate:d];
    }

}

Your choice result:

- (void)alertView:(UIAlertView *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
    // the user clicked one of the OK/Cancel buttons
    if (buttonIndex == 1)//Save
    {
        //do something

    }
    if (buttonIndex == 0)//NO
    {
        //do something
    }
}

Register the functions in the interface declaration:

@interface yourViewController ()
    -(void)checkSaving
    - (void)alertView:(UIAlertView *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
//...
@end

To call: [self checkSaving];

I wish this will help you.

Bo Persson
  • 90,663
  • 31
  • 146
  • 203
araferna
  • 71
  • 1
  • 5
0

The UIAlertView could be out of scope by the time the dismissAlert method is called (your checking for alert being nil will prevent this code crashing. There is, however, a better way of implementing this where alert will never be out of scope.

Your class that defines the networkAlert method should implement the <UIAlertViewDelegate> protocol. The code below allows you to intercept the user clicking the 'cancel' button and perform a custom action. The default action of pressing cancel is to close the UIAlertView.

@interface YourClassName : UIViewController <UIAlertViewDelegate> {}

@implementation YourClassName

-(void) networkAlert
{
    UIAlertView *netWork = [[UIAlertView alloc] initWithTitle:@"error" 
                                                      message:@"network has problems"
                                                     delegate:self 
                                            cancelButtonTitle:@"cancel" 
                                            otherButtonTitles:nil];
    [netWork show];
}

- (void) alertViewCancel:(UIAlertView*)alertView 
{
    what ever it is you want to do when the cancel button is pressed here
}
Jon Boydell
  • 834
  • 7
  • 8