简体   繁体   中英

Terminating due to Memory pressure

I have a collection view, which loads images from documents directory. When I try to laod these images to the collectionview, the app get crashed with a memory warning.

-(UICollectionViewCell*)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"Cell" forIndexPath:indexPath];
UIImage *cellImage;
if (indexPath.section == 0) {

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectoryPath = [paths objectAtIndex:0];
    NSString *folderPath = [documentsDirectoryPath  stringByAppendingPathComponent:@"Photos"];  // subDirectory
    NSString *filePath;    
    if ([[NSFileManager defaultManager] fileExistsAtPath:folderPath])
        filePath = [folderPath stringByAppendingPathComponent:[NSString stringWithFormat:@"Photo%d",indexpath.row]];

    cellImage = [UIImage imageWithContentsOfFile:filePath];

} else if (indexPath.section == 1){
    cellImage = [UIImage imageNamed:@"btn_vid.png"];
} else if (indexPath.section == 2){
    cellImage = [UIImage imageNamed:@"btn_mic.png"];
} else if (indexPath.section == 3){
    cellImage = [UIImage imageNamed:@"btn_1.png"];
}
UIImageView *imageView = (UIImageView *)[cell viewWithTag:100];
[imageView setImage:cellImage];

return cell;
}

What am I doing wrong?

Update: 在此处输入图片说明

The images are good sized because I take it from the phone's camera and save in documents directory

UPDATE:

I have received the suggestion of adding thumnails for the images and then load them from Airsource Ltd . I used this code to generate the thumbnail images instead of his and it worked. But I would like to know, which one is better.

+(UIImage*) generateThumbnailFromImage:(UIImage*)theImage
{
UIImage * thumbnail;
CGSize destinationSize = CGSizeMake(80,80);

UIGraphicsBeginImageContext(destinationSize);
[theImage drawInRect:CGRectMake(0,0,destinationSize.width, destinationSize.height)];
thumbnail = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

return thumbnail;
}

You're loading the full-sized image, but you're presumably only displaying a thumbnail. However, as things stand the UIImage needs to keep the full, decompressed image in memory in order to display the scaled down version, which is woefully inefficient.

To generate a thumbnail, load in the file as NSData, and then use the standard Apple code for generating thumbnails. Don't do too many in parallel., or you will hit exactly the same problem you already have

CGImageRef MyCreateThumbnailImageFromData (NSData * data, int imageSize)
{
    CGImageRef        myThumbnailImage = NULL;
    CGImageSourceRef  myImageSource;
    CFDictionaryRef   myOptions = NULL;
    CFStringRef       myKeys[3];
    CFTypeRef         myValues[3];
    CFNumberRef       thumbnailSize;

   // Create an image source from NSData; no options.
   myImageSource = CGImageSourceCreateWithData((CFDataRef)data,
                                               NULL);
   // Make sure the image source exists before continuing.
   if (myImageSource == NULL){
        fprintf(stderr, "Image source is NULL.");
        return  NULL;
   }

   // Package the integer as a  CFNumber object. Using CFTypes allows you
   // to more easily create the options dictionary later.
   thumbnailSize = CFNumberCreate(NULL, kCFNumberIntType, &imageSize);

   // Set up the thumbnail options.
   myKeys[0] = kCGImageSourceCreateThumbnailWithTransform;
   myValues[0] = (CFTypeRef)kCFBooleanTrue;
   myKeys[1] = kCGImageSourceCreateThumbnailFromImageIfAbsent;
   myValues[1] = (CFTypeRef)kCFBooleanTrue;
   myKeys[2] = kCGImageSourceThumbnailMaxPixelSize;
   myValues[2] = (CFTypeRef)thumbnailSize;

   myOptions = CFDictionaryCreate(NULL, (const void **) myKeys,
                   (const void **) myValues, 2,
                   &kCFTypeDictionaryKeyCallBacks,
                   & kCFTypeDictionaryValueCallBacks);

  // Create the thumbnail image using the specified options.
  myThumbnailImage = CGImageSourceCreateThumbnailAtIndex(myImageSource,
                                          0,
                                          myOptions);
  // Release the options dictionary and the image source
  // when you no longer need them.
  CFRelease(thumbnailSize);
  CFRelease(myOptions);
  CFRelease(myImageSource);

   // Make sure the thumbnail image exists before continuing.
   if (myThumbnailImage == NULL){
         fprintf(stderr, "Thumbnail image not created from image source.");
         return NULL;
   }

   return myThumbnailImage;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM