问题
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!
回答1:
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
}
回答2:
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.
来源:https://stackoverflow.com/questions/9459669/uialertview-exc-bad-access