UIImageView的内存泄漏

时间:2014-01-23 16:09:23

标签: ios iphone objective-c uiimageview uiimage

我目前正在iOS7中开展个人项目,我必须在Galarie滚动视图中显示多个图像。为此,我创建了一个UIImage,然后将其插入UIImageView。我将所有UIImageView存入NSMutableArray。 我在UIScrollView上显示所有图片。

通过我可以执行的测试,使用的内存可以超过500 MB。

如何优化内存?如何在相机基础应用程序中显示超过1000张照片?

提前谢谢你。亲切。

4 个答案:

答案 0 :(得分:1)

UICollectionView更适合您的问题!

UICollectionView类似于UITableView,只加载屏幕上显示的单元格。

UICollectionView是一个scrollview,但有内存管理。

答案 1 :(得分:1)

您需要根据scrollview位置设置延迟加载。仅加载可见屏幕的三倍(或更少,取决于内存需要)并实现UIScrollViewDelegate函数scrollviewDidScroll:以监听滚动事件。

在scrollViewDidScroll内部,您将要搜索您的图像数组(它应该是一个位置和文件名的数组,以获得最佳的内存释放)。如果滚动视图接近您的图像位置,则加载它并将其添加到屏幕。如果某些内容已经在屏幕上,但现在已足够远离屏幕并卸载,则将其从滚动视图中移除并释放对象(或者更好,重新使用它以进行下一次图像加载)。

了解PDFKitten。他们懒得加载PDF页面。您的图像可以完全相同的方式实现。

答案 2 :(得分: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];
}

答案 3 :(得分:0)

简单的解决方案是将原始图像保存到目录并将调整大小的图像分配给scrollview。此解决方案将使您能够以最少的内存使用量向scrollview添加更多图像。这是示例代码

  

- (IBAction为)selectImageBtnClicked:(ID)发送方   {

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

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {

[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]; }

     

- (void)proceedFURTHER:(UIImage *)pTakenImage {       UIImage * pResizedImage = [self resizeImageToMaxSize:640.0 anImage:pTakenImage];

[self saveOriginalImageToDir:pTakenImage];

//add pResizedImage to your scrolview here

[self.navigationController popViewControllerAnimated:YES]; }
     

- (UIImage *)resizeImageToMaxSize:(CGFloat)max anImage:(UIImage *)anImage {

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

CGImageSourceCreateWithData((CFDataRef)imgData,NULL);       if(!imageSource)           返回零;

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,options);

UIImage* scaled = [UIImage imageWithCGImage:imgRef];

CGImageRelease(imgRef);
CFRelease(imageSource);

return scaled; 
     

}

     

- (NSString *)getOriginalImageDirectoryPath {

     

NSArray * paths =   NSSearchPathForDirectoriesInDomains(NSLibraryDirectory,   NSUserDomainMask,YES);

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

[documentsPath stringByAppendingPathComponent:@“scaledimage.png”];

return filePath; }
     

- (void)saveOriginalImageToDir:(UIImage *)image {

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; }