iOS: crash in collectionview reoloaddata with UIImage

967 Views Asked by At

In my app I have this code:

- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView{
    return 1;
}

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
    return images.count;
}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{

    static NSString *identifier = @"gallerycell";

    UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath];

    UIImageView *backImageCell = (UIImageView*)[cell viewWithTag:100];
    [backImageCell setImage:[images objectAtIndex:indexPath.item]];

    if([indexPath row] == ((NSIndexPath*)[[collectionView indexPathsForVisibleItems] lastObject]).row){

[activity_view stopAnimating];
        [UIView animateWithDuration:0.8 animations:^{
            back.alpha = 0;
        }];
    }

    return cell;
}

the array images contains UIImage of 200x150 size, and their dimension in kb is about 42kb, a normal array of UIImage.

When I reload data for this collectionview I have a memory warning after 15 image... is there a way (as a thread) to don't have a memory warning?

2

There are 2 best solutions below

5
On

Don't store Images to Array, that's not a good practice. As the number of images or size of images increase it'll throw memory warnings and crash.

Alternatives:

  1. Store image names in array
  2. Store file path in array
  3. Store image url in array and use Async methods to load the image to your UITableView or UICollectionView
0
On

In addition to resizing the images, you can nil out the image when the cell scrolls out of view - just implement:

- (void)collectionView:(UICollectionView *)collectionView didEndDisplayingCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath 

Also, a trick to maintain a cache that will not swamp the system is to do as Midhun suggested in the comments - use imageWithContentsOfFile. Then create a NSCache, and stuff the images in it using the image name or some other identifying key. When you need an image, if its in the cache, pull it out. If not you can read it from the file system again. iOS will purge a NSCache if it needs more memory.