I'm not understanding why this is giving me a EXC_BAD_ACCESS. Basic background, im collecting and processing some information, and then using a modal view to let the user confirm if he want to continue.
I have a button on the navigation bar called continue, that calls my data prepare function.
- (void)viewDidLoad {
//Other stuff
UIBarButtonItem *next = [[UIBarButtonItem alloc]
initWithTitle:@"Next"
style:UIBarButtonItemStyleBordered
target:self
action:@selector(prepData)];
self.navigationItem.rightBarButtonItem = next;
[next release];
[super viewDidLoad];
}
prepData:
-(void)prepData{
/*
There's a bunch of stuff going on here, if "mensaje" is not an empty NSString, there is some kind of error that wont let me go on, if not, everything in the data is fine
*/
if(![mensaje isEqualToString:@""]){
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:nil
message:mensaje
delegate:nil
cancelButtonTitle:@"Aceptar"
otherButtonTitles:nil];
[alert show];
[alert release];
}else{
UIActionSheet *actionSheet = [[UIActionSheet alloc]
initWithTitle:@"¿Esta seguro que desea realizar estas operaciones?"
delegate:self
cancelButtonTitle:@"Cancelar"
开发者_JS百科 destructiveButtonTitle:@"Aceptar"
otherButtonTitles:nil];
[actionSheet showInView:self.view];
[actionSheet release];
}
}
If I debug, I can get all the way through the prepData(), as soon as I press continue I get a EXC_BAD_ACCESS. If I comment out the [actionSheet release]; I dont get the exception, but it is to my knowledge, that just like alert views, action sheets "stick around" until they show.
At least all books I've read state that, but its quite possible that I'm not understanding something in the autoreleasing.
Just for reference, the alert pops up just fine.
Anybody have any idea whats going on here?
Thanks, Stefano.
Edit: Figured it out, the above code for actions sheets and alert views is fine, the issue was that I was releasing something that was later trying to be autoreleased.
I have for loop that does this:
for(someConditions){
NSString *montoFormateado = [[[NSString alloc] initWithFormat:@"%.2lf",[monto doubleValue]] stringByReplacingOccurrencesOfString:@"." withString:@","];
[_postBuild setObject:[NSString stringWithString:montoFormateado] forKey:[NSString stringWithString:iidvar]];
[montoFormateado release];
}
postBuild = [_postBuild mutableCopy];
[_postBuild release];
Now, it seems the error was in the fact that by using [NSString strintWithString:montoFormateado] I was leaving that string up for autorelease later, but when I released _postBuild that string was getting released also, I removed that and just used setObject:montoFormateado and its working fine.
Its leaking memory, but I think thats for a diferent question, the exc_bad_access got solved.
The easiest way to find this kind of bug is to use the NSZombieEnabled environment variable.
When you get an EXC_BAD_ACCESS at the end of a call, it usually means that something is being autoreleased, but it's retain count is already 0 from you releasing it.
Check this post, it'll save your life a lot of times. If that doesn't work, leave a comment and we'll put our debugging caps back on :)
I think there's one release too many in the code you didn't show (in the "There's a bunch of stuff going on here, if "mensaje" is not an empty NSString" block).
There's nothing wrong with your actionSheet code. As you say, it should deallocate itself once it's no longer on screen. But if you over-released one of the sub-views of self.view
then it could cause a crash when the autorelease pool is drained.
In both cases, if you're gonna "release", you better "retain" first.
In the case of the UIActionSheet - I believe the view passed into showInView is retaining a copy of the actionsheet.
In the AlertView this is not the case.
Maybe you are releasing the UIAlertView before its used, try removing the release statement and declare the UIAlertView as auto release (though it should be fine the way you have it)
if(![mensaje isEqualToString:@""]){
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:nil
message:mensaje
delegate:nil
cancelButtonTitle:@"Aceptar"
otherButtonTitles:nil] autorelease];
[alert show];
Another thing that it might be is that you are releasing these guys again on some call back or something, you should check you arent doing that, and like the poster above me said, you can use zombies to figure this stuff out as well.
精彩评论