Skip to content

Commit

Permalink
Wrap fetch in NSBlockOperation
Browse files Browse the repository at this point in the history
Wrapping each image in a fetch operation guarantees that the app will get 60 FPS
because it avoids returning all 100+ images in a single frame. This is most
noticeable on an iPad 3, which can only perform ~7 image updates per frame.
  • Loading branch information
William Green committed Feb 5, 2016
1 parent 16b7ecf commit e23d5d4
Showing 1 changed file with 37 additions and 12 deletions.
49 changes: 37 additions & 12 deletions FastImageCache/FastImageCacheDemo/Classes/FICDPhotosTableViewCell.m
Expand Up @@ -27,7 +27,9 @@ @interface FICDPhotosTableViewCell () <UIGestureRecognizerDelegate> {

#pragma mark

@implementation FICDPhotosTableViewCell
@implementation FICDPhotosTableViewCell {
NSMutableArray *_operations;
}

@synthesize delegate = _delegate;
@synthesize usesImageTable = _usesImageTable;
Expand All @@ -40,25 +42,46 @@ - (void)setPhotos:(NSArray *)photos {
if (photos != _photos) {
_photos = [photos copy];

for (NSInteger i = 0; i < [_imageViews count]; i++) {
UIImageView *imageView = [_imageViews objectAtIndex:i];
for (NSOperation *operation in _operations) {
[operation cancel];
}
[_operations removeAllObjects];

if (i < [_photos count]) {
if (_usesImageTable) {
for (UIImageView *imageView in _imageViews) {
if (imageView.image) {
[imageView setImage:nil];
}
}
for (NSInteger i = 0; i < [_photos count]; i++) {
UIImageView *imageView = [_imageViews objectAtIndex:i];
FICDPhoto *photo = [_photos objectAtIndex:i];

if (_usesImageTable) {
__block __weak NSBlockOperation *operation;
operation = [NSBlockOperation blockOperationWithBlock:^{
if ([operation isCancelled]) {
return;
}
[[FICImageCache sharedImageCache] retrieveImageForEntity:photo withFormatName:_imageFormatName completionBlock:^(id<FICEntity> entity, NSString *formatName, UIImage *image) {
// This completion block may be called much later. We should check to make sure this cell hasn't been reused for different photos before displaying the image that has loaded.
if (photos == [self photos]) {
[imageView setImage:image];
if ([operation isCancelled]) {
return;
}
[imageView setImage:image];
[_operations removeObject:operation];
}];
} else {
}];
[_operations addObject:operation];
[[NSOperationQueue mainQueue] addOperation:operation];
}
} else {
for (NSInteger i = 0; i < [_imageViews count]; i++) {
UIImageView *imageView = [_imageViews objectAtIndex:i];
if (i < [_photos count]) {
FICDPhoto *photo = [_photos objectAtIndex:i];
[imageView setImage:[photo thumbnailImage]];
} else {
[imageView setImage:nil];
}
} else {
// Last row might not be full
[imageView setImage:nil];
}
}
}
Expand Down Expand Up @@ -115,6 +138,8 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus
}

_imageViews = [imageViews copy];

_operations = [NSMutableArray array];
}

return self;
Expand Down

0 comments on commit e23d5d4

Please sign in to comment.