I am developing a similar program like Photos in the iPhone using ALAssetLibrary. I am trying to load the images in a scrollview. Everything works fine when the album has small
I personally put all of my UIImageView
objects on my UIScrollView
, but only set the image property for them for those that are currently visible (and clear the image property for those that are no longer visible). If you have thousands of images, perhaps even that is too wasteful (perhaps you don't even want to keep the UIImageView
objects, even without their image
property set, around), but if you're dealing with hundreds, I find it is a nice easy solution, addressing the key problem of the memory consumed by the UIImage
objects:
- (void)viewDidLoad
{
[super viewDidLoad];
self.scrollView.delegate = self;
// all of my other viewDidLoad stuff...
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self loadVisibleImages];
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
[self loadVisibleImages];
}
- (void)loadVisibleImages
{
CGPoint contentOffset = self.scrollView.contentOffset;
CGRect contentFrame = self.scrollView.bounds;
contentFrame.origin = contentOffset;
for (UIImageView *imageView in _imageViews) // _imageViews is (obviously) my array of images
{
if (CGRectIntersectsRect(contentFrame, imageView.frame))
{
imageView.image = ... // set the image property
}
else
{
imageView.image = nil;
}
}
}
This is a snippet from some code that's doing a bunch of other stuff, so clearly your implementation will differ significantly, but it shows how you can use scrollViewDidScroll
to determine what images are visible and load/unload images appropriately. You could probably alter further if you want to also remove/add the UIImageView
objects, too, but clearly the logic of "is this imageview visible" would have to be changed, rather than leveraging the frame
of all of the UIImageView
objects.
I'm not sure if I'm reading your code right, but do you also have all of your UIImage
objects sitting in a dictionary, too? That's pretty extravagant use of memory, itself. I usually keep the actual images in some persistent store (e.g. I use Documents
folder, though you could use Core Data
or SQLite
, though the latter two impose a significant performance hit for large images). The only images I keep in memory are the ones actively used by the UI and I'll use a NSCache
object to keep a few around for performance reasons, but I otherwise pull them from persistent storage, not active memory.
You should use scroll view delegation to determine which images would be showing on the screen at the current time, and only have those loaded in memory.
Also, if you are displaying a much smaller than the actual image size, you should resize the image and use the smaller image.
why not use UICollectionView
and UICollectionViewController
classes? UICollectionViewController
reference here
sample code here.
Your images will end up being instances of UICollectionViewCell
. The data source and delegate protocol methods are similar to the UITableView methods. i.e. they provide a mechanism where the UICollectionViewController
will reuse the UICollectionViewCells
.
The benefit of using these classes is that they are used similarly to UITableViewControllers
and they assist you with the memory pressure issues that you are having.
good luck!