У меня проблема с приложением для просмотра фотографий, которое я написал.Несколько UIImageViews в UIScrollView и сбоях
У меня есть UITabBarController с UINavigationController внутри. Сначала UINavigationController отображает UITableView. При выборе он подталкивает другой UIViewController (Индивидуальный фотоальбом) вместе с NSArray фотографий. Этот контроллер содержит UIScrollView/UIPageControl, который отображает несколько UIViewControllers, в которых есть UIImageView.
Приложение изначально отлично работает. Он загружает каждое изображение для каждого альбома, и вы можете вернуться с панели навигации. Проблема в том, что после примерно 180 изображений приложение начинает выдавать предупреждения о памяти и, в конечном счете, сбрасывает метало «Program received signal:« 0 ». Warning: check_safe_call: не удалось восстановить текущий фрейм, который, как я полагаю, связан с низкой памятью. Это невероятно разочаровывает, потому что я проверил и нет утечек, и каждый dealloc называется так, как должен. Методы dealloc освобождают каждое сохраненное свойство и устанавливают их на нуль.
Если вы проверяете инструменты, это показывает, что использование памяти постепенно увеличивается после просмотра каждого альбома. Он освобождает некоторую память, но не все. например если альбом использует 1 МБ для отображения 0,9 МБ, может быть выпущен.
Любая помощь будет оценена по достоинству. Это последний вопрос, прежде чем я его выпустил.
EDIT: Это ссылка на основные файлы проекта. http://www.mediafire.com/?nztrd1yhzoo
AlbumsViewController (толкает индивидуальный "albumviewcontroller")
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSMutableDictionary *dictThisItem = [self.arrAlbums objectAtIndex:[indexPath row]];
NSString *strBand = [dictThisItem objectForKey:@"album"];
NSMutableArray *arrThesePhotos = [[self.arrAlbums objectAtIndex:[indexPath row]] objectForKey:@"photos"];
if (self.albumViewController == nil){
self.albumViewController = [[AlbumViewController alloc] initWithNibName:nil bundle:nil];
}
albumViewController.hidesBottomBarWhenPushed = YES;
[self.navigationController pushViewController:albumViewController animated:YES];
self.albumViewController.arrPhotos = arrThesePhotos;
[albumViewController populateScroller];
}
AlbumViewController
- (void)populateScroller {
imagesScroller.pagingEnabled = YES;
imagesScroller.contentSize = CGSizeMake(imagesScroller.frame.size.width * [self.arrPhotos count], 380);
imagesScroller.showsHorizontalScrollIndicator = NO;
imagesScroller.showsVerticalScrollIndicator = NO;
imagesScroller.scrollsToTop = NO;
imagesScroller.delegate = self;
imagesScroller.backgroundColor = [UIColor blackColor];
[imagesScroller scrollRectToVisible:CGRectMake(0.0, 0.0, 320.0, 480.0) animated:NO];
pageControl.numberOfPages = [self.arrPhotos count];
pageControl.currentPage = 0;
pageControl.backgroundColor = [UIColor blackColor];
NSMutableArray *controllers = [[NSMutableArray alloc] init];
for (int i = 0; i < [self.arrPhotos count]; i++) {
CGRect frame = imagesScroller.frame;
frame.origin.x = frame.size.width * i;
frame.origin.y = 0;
NSString *strImagePath = [[self.arrPhotos objectAtIndex:i] stringByReplacingOccurrencesOfString:@"iPhone" withString:@"iPhone_thumbnail"];
ImageViewController *imageViewController = [ImageViewController alloc];
imageViewController.localImage = YES;
imageViewController.albumViewController = self;
[imageViewController initWithPhotoName:strImagePath];
[controllers addObject:imageViewController];
imageViewController.view.frame = frame;
[imagesScroller addSubview:imageViewController.view];
[imageViewController release];
}
self.viewControllers = controllers;
[controllers release];
}
ImageViewController
- (void)viewDidLoad {
self.navigationShown = NO;
Cache *cache = [[Cache alloc] init];
[cache release];
NSString *strURL = [@"http://www.marklatham.co.uk" stringByAppendingString:self.strThisPhoto];
NSString *strTmpPrefix = (self.localImage) ? @"_tmp_rockphotothumb_" : @"_tmp_rockphotolarge_";
// Cache Paths
NSArray *arrPaths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *strLocalPath = [[arrPaths objectAtIndex:0] stringByAppendingString:@"/"];
NSString *strPrefix = (strTmpPrefix != nil) ? strTmpPrefix : @"_tmp_rockphotolarge_";
NSMutableArray *arrImagePaths = (NSMutableArray *)[strURL componentsSeparatedByString:@"/"];
// Check cache
NSString *strEntireLocalCache = [strLocalPath stringByAppendingString:[strPrefix stringByAppendingString:[arrImagePaths objectAtIndex:[arrImagePaths count]-1]]];
if ([[NSFileManager defaultManager] fileExistsAtPath:strEntireLocalCache]){
UIImageView *imvImageView = [UIImageView alloc];
UIImage *image = [[UIImage imageWithContentsOfFile:strEntireLocalCache] autorelease];
[imvImageView initWithImage:image];
CGSize imgSize = image.size;
CGFloat fltWidth = imgSize.width;
CGFloat fltHeight = imgSize.height;
// If landscape rotate image
if (fltWidth > fltHeight){
imvImageView.frame = CGRectMake(-80.0, 80.0, 481.0, 320.0);
CGAffineTransform rotate = CGAffineTransformMakeRotation(-1.57079633);
[imvImageView setTransform:rotate];
}else{
imvImageView.frame = CGRectMake(0.0, 0.0, 320.0, 481.0);
}
[self.view addSubview:imvImageView];
[imvImageView release];
}else{
// Data URL Downloading
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
NSData *datImageData = [NSData dataWithContentsOfURL: [NSURL URLWithString:strURL]];
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
[datImageData writeToFile:strEntireLocalCache atomically:YES];
UIImageView *imvImageView = [UIImageView alloc];
UIImage *image = [[UIImage imageWithData: datImageData] autorelease];
[imvImageView initWithImage:image];
CGSize imgSize = image.size;
CGFloat fltWidth = imgSize.width;
CGFloat fltHeight = imgSize.height;
// If landscape rotate image
if (fltWidth > fltHeight){
imvImageView.frame = CGRectMake(-80.0, 80.0, 481.0, 320.0);
CGAffineTransform rotate = CGAffineTransformMakeRotation(-1.57079633);
[imvImageView setTransform:rotate];
}else{
imvImageView.frame = CGRectMake(0.0, 0.0, 320.0, 481.0);
}
[self.view addSubview:imvImageView];
[imvImageView release];
}
}
Я просто предполагал, что вы просачивались, так как вы сказали, что это бросает предупреждения о памяти. Вы не получили бы предупреждения о памяти, если у вас не хватит памяти, и единственный способ исчерпать память с течением времени - это утечка памяти. ;) Используйте ObjectAlloc и используйте опцию «Созданный и все еще живой», чтобы узнать, что такое 0,1 МБ, которое не выпущено. –
ObjectAlloc может часто скрывать истинное использование памяти для элементов отображения. Для более точного считывания общего использования памяти вам нужно обратиться к инструменту монитора памяти. –
В соответствии с инструментом утечки нет утечек, и если вы добавите NSLog в dealloc в ImageViewController, он покажет, что он вызывается после изображения, если он добавлен в UIScrollView (и предположительно массив контроллеров). Что именно показывает «Реальная память» в инструменте монитора памяти? Это активная память? Если это так, я полностью смущен, так как показывает, что значение растет после загрузки каждого изображения, но вряд ли какая-либо память освобождается при вызове dealloc в «ImageViewController». Не могли бы вы взглянуть на проект (см. Сообщение), чтобы увидеть, видите ли вы что-нибудь очевидное. –