我有一个详细视图。其中一个值是指向图像的URL。
如果网址不是nil,则会创建一个临时视图以显示进度条,并在后台下载NSURLConnection
的图像。准备好后,我删除进度视图,创建并添加一个新的图像视图,用foto替换旧的进度视图。
尝试使用[[self.view viewWithTag:1100] removeFromSuperview];
删除视图时,我总是得到EXC_BAD_ACCESS。我已经检查了每行的代码,无法猜出错误的位置,所以也许我错过了一些规则。
仪器给了我以下信息:
# Address Category Event Type RefCt Timestamp Size Responsible Library Responsible Caller 0 0x5ded960 CALayer Malloc 1 00:10.772.601 48 UIKit -[UIView _createLayerWithFrame:] 1 0x5ded960 CALayer Zombie -1 00:14.720.076 0 QuartzCore -[CALayerArray copyWithZone:]
这是代码:
- (void) loadDataIntoView
{
// Create the View without the photo
self.nombreTextView.text = self.evento.nombre;
self.fechaTextField.text = @"Del 12 de Junio de 2010 al 3 de Octubre de 2011";
// Check is a photo url exists
if (self.evento.foto) {
// Download the photo in background
self.fotoConnection = [NSURLConnection connectionWithRequest:
[NSURLRequest requestWithURL:self.evento.foto]
delegate:self];
// Erros are handled by the delegate methods
// This error should never happen
if (!self.fotoConnection) {
NSLog(@"Error creating connection");
exit(0);
}
// Create the entradilla View
UITextView *entradillaTextView = [[UITextView alloc] init];
entradillaTextView.frame = CGRectMake(26, 216, 280, 145);
entradillaTextView.text = self.evento.entradilla;
entradillaTextView.tag = 1000;
[self.view addSubview:entradillaTextView];
[entradillaTextView release];
// Create the progess View
UIView *progressView = [[UIView alloc] initWithFrame:CGRectMake(26, 76, 270, 130)];
progressView.tag = 1100;
// Create progressView Label
UILabel *legendLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 270, 20)];
legendLabel.text = @"descargando fotografía";
legendLabel.font = [UIFont systemFontOfSize:11];
legendLabel.textColor = [UIColor lightGrayColor];
legendLabel.textAlignment = UITextAlignmentCenter;
// Create progressView progressBar
UIProgressView *auxView = [[UIProgressView alloc] initWithFrame:CGRectMake(35, 20, 200, 40)];
self.progressBar = auxView;
[auxView release];
self.progressBar.tag = 1200;
[progressView addSubview:legendLabel];
[legendLabel release];
[progressView addSubview:progressBar];
[progressBar release];
[self.view addSubview:progressView];
[progressView release];
} else {
// Create the entradilla View without any foto view space on top
UITextView *entradillaTextView = [[UITextView alloc] init];
entradillaTextView.frame = CGRectMake(26, 76, 280, 283);
entradillaTextView.text = self.evento.entradilla;
entradillaTextView.tag = 1000;
[self.view addSubview:entradillaTextView];
[entradillaTextView release];
}
// Configure the ToolBar
// Create the favourites button if evento is not favourite
UIBarButtonItem *favouritesButton;
if (!self.evento.isFavourite) {
NSString *imagePath = [[NSBundle mainBundle] pathForResource:@"29-heart" ofType:@"png"];
UIImage *addFavouriteImage = [UIImage imageWithContentsOfFile:imagePath];
favouritesButton = [[UIBarButtonItem alloc] initWithImage:addFavouriteImage style:UIBarButtonItemStylePlain target:self action:@selector(addFavoritosButtonPressed)];
// favouritesButton = [[UIBarButtonItem alloc] initWithTitle:@"+ Favoritos" style:UIBarButtonItemStyleBordered target:self action:@selector(addFavoritosButtonPressed)];
} else {
favouritesButton = [[UIBarButtonItem alloc] initWithTitle:@"- Favoritos" style:UIBarButtonItemStyleBordered target:self action:@selector(removeFavoritosButtonPressed)];
}
// Create the Web buttom
UIBarButtonItem *webButton = [[UIBarButtonItem alloc] initWithTitle:@"Mostrar Web" style:UIBarButtonItemStyleBordered target:self action:@selector(webButtonPressed)];
// Create the Map buttom
UIBarButtonItem *mapButton = [[UIBarButtonItem alloc] initWithTitle:@"Mostrar Mapa" style:UIBarButtonItemStyleBordered target:self action:@selector(mapButtonPressed)];
self.toolbarItems = [NSArray arrayWithObjects:favouritesButton, webButton, mapButton, nil];
[favouritesButton release];
[webButton release];
[mapButton release];
}
#pragma Mark -
#pragma Mark NSURLConnection Delegate
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
NSHTTPURLResponse *resp = (NSHTTPURLResponse *) response;
if ((resp.statusCode >= 200) && (resp.statusCode < 300)) {
// OK status Code
// Prepare the temp array
self.fotoData = [NSMutableData data];
// Get the lenght of data to download for progress bar
self.dataSizeToDownload = resp.expectedContentLength;
self.dataSizeDownloaded = 0;
} else {
// Wrong status Code
self.fotoData = nil;
self.progressBar = nil;
[connection cancel];
self.fotoConnection = nil;
// Reconfigure the View
// Remove the old entradilla
[[self.view viewWithTag:1000] removeFromSuperview];
// Create the repositioned entradilla View
UITextView *entradillaTextView = [[UITextView alloc] init];
entradillaTextView.frame = CGRectMake(26, 76, 280, 283);
entradillaTextView.text = self.evento.entradilla;
entradillaTextView.tag = 1000;
[self.view addSubview:entradillaTextView];
[entradillaTextView release];
}
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[self.fotoData appendData:data];
self.dataSizeDownloaded = self.dataSizeDownloaded + (float)data.length;
if ( self.dataSizeToDownload != 0) {
float prog = (float)( self.dataSizeDownloaded / self.dataSizeToDownload );
[self performSelectorOnMainThread:@selector(updateProgressBarWithValue:) withObject:[NSNumber numberWithFloat:prog] waitUntilDone:NO];
}
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
// If no error create a new View and Reload the data
self.fotoConnection = nil;
if (self.fotoData) {
self.progressBar = nil;
// !!!!!!!!! THIS IS THE EXC_BAD_ACCESS !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
[[self.view viewWithTag:1100] removeFromSuperview];
UIImageView *fotoImageView = [[UIImageView alloc] initWithImage:
[UIImage imageWithData:self.fotoData]];
fotoImageView.frame = CGRectMake( 26, 76, 270, 130);
fotoImageView.contentMode = UIViewContentModeScaleAspectFit;
[self.view addSubview:fotoImageView];
[fotoImageView release];
[self.view reloadInputViews];
} else {
// Error downloading foto
}
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
self.fotoConnection = nil;
self.fotoData = nil;
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:error.description message:nil delegate:nil cancelButtonTitle:@"aceptar" otherButtonTitles:nil];
[alert show];
[alert release];
}
- (void) updateProgressBarWithValue:(NSNumber *)value
{
float progress = [value floatValue];
NSLog(@"Progress %f", progress);
//self.progressBar.progress = progress;
}
答案 0 :(得分:1)
最后我自己明白了。我只是离开应用程序几个小时,然后我发现了一个不应该存在的[progressBar release]
,因为我已将其声明为属性。它与其他代码不一致,我只是声明了本地变量,所以每次检查代码时都没有意识到。