2014-01-23 5 views
1

В настоящее время я работаю над личным проектом в iOS7, и я должен отображать несколько изображений в виде прокрутки Galarie. Для этого я создал UIImage, затем вставляю его в UIImageView. Я размещаю все свои UIImageView в NSMutableArray. Я покажу все фотографии на UIScrollView.Утечка памяти от UIImageView

С тестом, который я мог выполнить, используемая память может превышать 500 МБ.

Как оптимизировать память? Как приложение базовой камеры для вас может отображать более 1000 фотографий?

Заранее спасибо. Сердечно.

+3

Ленивая загрузка и делает эскизы изображения, когда не отображается на весь экран. – rckoenes

ответ

1

UICollectionView более подходит для вашей проблемы!

UICollectionView как UITableView, загружает только ячейки, отображаемые на экране.

UICollectionView - это scrollview, но с управлением памятью.

+3

Развернуть свою точку! Объясните, почему это лучше. – BooRanger

+0

Привет, я попробовал UICollectionView, чем я не знал. Это очень мощный, но у меня еще проблема с памятью. Это сумасшедшая ситуация.Я попытаюсь сжать UIImage. – user2724028

+0

Это не решение проблемы OPs –

1

Вам нужно настроить ленивую загрузку в зависимости от местоположения прокрутки. Загружайте только три раза видимый экран (или меньше, в зависимости от потребности в памяти) и реализуйте функцию UIScrollViewDelegate scrollviewDidScroll: для прослушивания прокрутки событий.

Внутри scrollViewDidScroll вы захотите найти свой массив изображений (это должен быть массив местоположений и имен файлов для лучшего восстановления памяти). Если scrollview приближается к вашему местоположению изображения, загрузите его и добавьте на экран. Если что-то уже было на экране, но теперь достаточно далеко, чтобы отключиться от экрана и выгрузить, а затем удалить его из прокрутки и освободить объект (или, лучше, повторно использовать его для следующей загрузки изображения).

Посмотрите на PDFKitten. Они делают ленивую загрузку PDF-страниц. Ваши изображения могут быть реализованы точно так же.

0

Я столкнулся с этой же проблемой пару лет назад, когда я использовал полноразмерные изображения в своих UIImageViews. У моего приложения все время не хватало памяти на самом iPhone 4. По какой-то причине он отлично работал на симуляторе iPhone.

Вы должны уменьшить исходные изображения с помощью «UIImage + Resize», чтобы отображать изображения предварительного просмотра в вашем UIScrollView. Когда пользователь нажимает на одно из изображений, вы можете показать им большую/полную версию.

Download it from here.

CGSize buttonSize = CGSizeMake(100, 100); 

UIImage * newImage = [[UIImage alloc] initWithContentsOfFile: pathToImage]; 
if(newImage) 
{ 
    // this "resizedimage" image is what you want to pass to setImage 
    UIImage * resizedImage = [newImage resizedImage: buttonSize interpolationQuality: kCGInterpolationLow]; 
} 
0

Простое решение состоит в том, чтобы сохранить исходное изображение в папку и присвоить уменьшенное изображение, чтобы Scrollview. Это решение позволит вам добавить большее количество изображений в scrollview с минимальным использованием памяти.Вот пример кода

- (IBAction) selectImageBtnClicked: (идентификатор) отправитель {

UIImagePickerController * picker = [[UIImagePickerController alloc] init]; 
picker.delegate = self; 
picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary; 
[self presentViewController:picker animated:YES completion:nil]; 
[picker release]; } 

- (Недействительными) imagePickerController: (UIImagePickerController *) Высотные didFinishPickingMediaWithInfo: (NSDictionary *) Информация {

[picker dismissViewControllerAnimated:YES completion:nil]; 
[[picker parentViewController] dismissViewControllerAnimated:YES 

завершение: ноль];

UIImage *pTakenImage = [info objectForKey:UIImagePickerControllerEditedImage]; 
if (!pTakenImage) 
    pTakenImage = [info objectForKey:UIImagePickerControllerOriginalImage]; 

[self performSelectorOnMainThread:@selector(proceedFURTHER:) 

withObject: pTakenImage waitUntilDone: NO]; }

- (недействительными) proceedFURTHER: (UIImage *) pTakenImage { UIImage * pResizedImage = [собственной resizeImageToMaxSize: 640,0 Animage: pTakenImage];

[self saveOriginalImageToDir:pTakenImage]; 

//add pResizedImage to your scrolview here 

[self.navigationController popViewControllerAnimated:YES]; } 

- (UIImage *) resizeImageToMaxSize: (CGFloat) макс Animage: (UIImage *) Animage {

NSData * imgData = UIImageJPEGRepresentation(anImage, 1); 
CGImageSourceRef imageSource = 

CGImageSourceCreateWithData ((CFDataRef) imgData, NULL); if (! ImageSource) return nil;

CFDictionaryRef options = 

(CFDictionaryRef) [NSDictionary dictionaryWithObjectsAndKeys:

(ID) kCFBooleanTrue, (ID) kCGImageSourceCreateThumbnailWithTransform,

(ID) kCFBooleanTrue, (ID) kCGImageSourceCreateThumbnailFromImageIfAbsent,

(ID) [ NSNumber numberWithFloat: max], (id) kCGImageSourceThumbnailMaxPixelSize, nil];

CGImageRef imgRef = 

CGImageSourceCreateThumbnailAtIndex (ImageSource, 0, опционы);

UIImage* scaled = [UIImage imageWithCGImage:imgRef]; 

CGImageRelease(imgRef); 
CFRelease(imageSource); 

return scaled; 

}

- (NSString *) getOriginalImageDirectoryPath {

NSArray * дорожки = NSSearchPathForDirectoriesInDomains (NSLibraryDirectory, NSUserDomainMask, ДА);

NSString *documentsPath = [paths objectAtIndex:0]; 
NSString *filePath = 

[documentsPath stringByAppendingPathComponent: @ "scaledimage.png"];

return filePath; } 

- (Недействительными) saveOriginalImageToDir: (UIImage *) изображение {

NSString *filePath = [self getOriginalImageDirectoryPath]; 

if([[NSFileManager defaultManager] fileExistsAtPath:filePath]) 
    [[NSFileManager defaultManager] removeItemAtPath:filePath error:nil]; 

NSData *data = UIImagePNGRepresentation(image); 

[data writeToFile:filePath atomically:YES]; 
data = nil; } 
Смежные вопросы