Graphics Reference
In-Depth Information
Listing 14.2 shows an updated
-collectionView:cellForItemAtIndexPath:
method that
uses GCD to load the images on a low priority background queue instead of on the main
thread. We switch back to the main thread before we actually apply the newly loaded image
to the cell because it's unsafe to access views on a background thread.
Because cells are recycled in a
UICollectionView
, we can't be sure that the cell hasn't
been reused with a different index in the meantime while we were loading the image. To
avoid images being loaded into the wrong cells, we tag the cell with the index before
loading and check that the tag hasn't changed before we set the image.
Listing 14.2
Using GCD to Load the Carousel Images
- (
UICollectionViewCell
*)collectionView:(
UICollectionView
*)collectionView
cellForItemAtIndexPath:(
NSIndexPath
*)indexPath
{
//dequeue cell
UICollectionViewCell
*cell =
[collectionView
dequeueReusableCellWithReuseIdentifier
:
@"Cell"
forIndexPath
:indexPath];
//add image view
const
NSInteger
imageTag =
99
;
UIImageView
*imageView = (
UIImageView
*)[cell
viewWithTag
:imageTag];
if
(!imageView)
{
imageView = [[
UIImageView
alloc
]
initWithFrame
:
cell.
contentView
.
bounds
];
imageView.
tag
= imageTag;
[cell.
contentView
addSubview
:imageView];
}
//tag cell with index and clear current image
cell.
tag
= indexPath.
row
;
imageView.
image
=
nil
;
//switch to background thread
dispatch_async
(
dispatch_get_global_queue
(
DISPATCH_QUEUE_PRIORITY_LOW
,
0
), ^{
//load image
NSInteger
index = indexPath.
row
;
NSString
*imagePath =
self
.
imagePaths
[index];
UIImage
*image = [
UIImage
imageWithContentsOfFile
:imagePath];
//set image on main thread, but only if index still matches up
dispatch_async
(
dispatch_get_main_queue
(), ^{