0

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?

artless noise
  • 21,212
  • 6
  • 68
  • 105
cyclingIsBetter
  • 17,447
  • 50
  • 156
  • 241
  • Interesting that you are using indexPath.item instead of indexPath.row - does the tableview set that value? I never saw it used before (frankly didn't know it existed til I read the class description). – David H Nov 06 '13 at 16:23
  • I cannot see anything odd about the code above. I suggest instead of loading images, try getting the imageView, and just setting its background color or something, and see what happens (i.e. avoid touching the image array at all). I suspect your problem is something quite different. You are using ARC, right? – David H Nov 06 '13 at 16:25
  • 1
    @DavidH: `indexPath.item` is used for UICollectionView and `indexPath.row` is used for UITableView – Midhun MP Nov 06 '13 at 16:27
  • @MidhunMP, hah - I am using a collectionView myself, and using the "row" value not the item number, but its working. Guess iOS sets both row and item to the same value. I'll go see right now! Thanks! – David H Nov 06 '13 at 16:28
  • it's not a discussion about "row" and "item" :-) , it work fine with row too. I'm using ARC and I take these image from an album in camera roll – cyclingIsBetter Nov 06 '13 at 16:31

2 Answers2

2

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
Midhun MP
  • 103,496
  • 31
  • 153
  • 200
  • If the images are in his bundle, and he's loading them using imageNamed, then the system is going to cache the image anyway. You are correct if he is downloading images, and the images are large (his seem pretty small - a 100 of them would fit in 4M of memory). – David H Nov 06 '13 at 16:27
  • @DavidH: He can use `imageWithContentsOfFile`. It' won't cache the image. In the above code one probability is the array with images. – Midhun MP Nov 06 '13 at 16:30
  • I take my UIImages from an album in camera roll with ALAssetsGroup and I fill an NSMutableArray with these images; before to reload data I crate another array that I fill with thumb of 200x150 size. But I have a memory warning – cyclingIsBetter Nov 06 '13 at 16:33
  • @blackguardian: Now I got the issue, the issue is due to that Thumbnail code and array storage, You'll surely ask how I said this ? Well, Me also got a similar issue 1 year back. I posted an issue here: http://stackoverflow.com/questions/14016879/error-occuring-when-loading-photolibrary-images-error-figcreatecgimagefromjpe Me removed the thumbnail code and used the code displayed on the question. It worked for me :) – Midhun MP Nov 06 '13 at 16:36
  • the problem is not the storage of thumb in array, it work fine and without memory warning. The problem is when I populate the collectionview. I found a solution in this page http://stackoverflow.com/questions/17161755/uicollectionview-image-on-cell-memory-warning but I have a crash "[UIImage pathExtension]: unrecognized selector sent to instance" – cyclingIsBetter Nov 06 '13 at 17:00
0

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.

David H
  • 40,852
  • 12
  • 92
  • 138