Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6914615
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 27, 20262026-05-27T09:22:13+00:00 2026-05-27T09:22:13+00:00

I have a UITableView consisting of roughly 10 subclassed UITableViewCell s named TBPostSnapCell. Each

  • 0

I have a UITableView consisting of roughly 10 subclassed UITableViewCells named TBPostSnapCell. Each cell, when initialised, sets two of its variables with UIImages downloaded via GCD or retrieved from a cache stored in the user’s documents directory.

For some reason, this is causing a noticeable lag on the tableView and therefore disrupting the UX of the app & table.

Please can you tell me how I can reduce this lag?

tableView… cellForRowAtIndexPath:

if (post.postType == TBPostTypeSnap || post.snaps != nil) {

        TBPostSnapCell *snapCell = (TBPostSnapCell *) [tableView dequeueReusableCellWithIdentifier:snapID];

        if (snapCell == nil) {

            snapCell = [[[NSBundle mainBundle] loadNibNamed:@"TBPostSnapCell" owner:self options:nil] objectAtIndex:0];

            [snapCell setPost:[posts objectAtIndex:indexPath.row]];

            [snapCell.bottomImageView setImage:[UIImage imageNamed:[NSString stringWithFormat:@"%d", (indexPath.row % 6) +1]]];
        }

    [snapCell.commentsButton setTag:indexPath.row];
    [snapCell.commentsButton addTarget:self action:@selector(comments:) forControlEvents:UIControlEventTouchDown];
    [snapCell setSelectionStyle:UITableViewCellSelectionStyleNone];

    return snapCell;
}

TBSnapCell.m

- (void) setPost:(TBPost *) _post {

    if (post != _post) {
        [post release];
        post = [_post retain];
    }
    ...

    if (self.snap == nil) {

        NSString *str = [[_post snaps] objectForKey:TBImageOriginalURL];
        NSURL *url = [NSURL URLWithString:str];
        [TBImageDownloader downloadImageAtURL:url completion:^(UIImage *image) {
            [self setSnap:image];
        }];
    }

    if (self.authorAvatar == nil) {
        ...
        NSURL *url = [[[_post user] avatars] objectForKey:[[TBForrstr sharedForrstr] stringForPhotoSize:TBPhotoSizeSmall]];

        [TBImageDownloader downloadImageAtURL:url completion:^(UIImage *image) {
            [self setAuthorAvatar:image];
        }];
        ...
    }

}

TBImageDownloader.m

+ (void) downloadImageAtURL:(NSURL *)url completion:(TBImageDownloadCompletion)_block {

    if ([self hasWrittenDataToFilePath:filePathForURL(url)]) {
        [self imageForURL:filePathForURL(url) callback:^(UIImage * image) {
            _block(image); //gets UIImage from NSDocumentsDirectory via GCD
        }];
        return;
    }

    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
    dispatch_async(queue, ^{
        UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:url]];
        dispatch_async(dispatch_get_main_queue(), ^{
            [self writeImageData:UIImagePNGRepresentation(image) toFilePath:filePathForURL(url)];
            _block(image);
        });
    });
}
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-27T09:22:14+00:00Added an answer on May 27, 2026 at 9:22 am

    First thing to try is converting DISPATCH_QUEUE_PRIORITY_HIGH (aka ONG MOST IMPORTANT WORK EVER FORGET EVERYTHING ELSE) to something like DISPATCH_QUEUE_PRIORITY_LOW.

    If that doesn’t fix it you could attempt to do the http traffic via dispatch_sources, but that is a lot of work.

    You might also just try to limit the number of in flight http fetches with a semaphore, the real trick will be deciding what the best limit is as the “good” number will depend on the network, your CPUs, and memory pressure. Maybe benchmark 2, 4, and 8 with a few configurations and see if there is enough pattern to generalize.

    Ok, lets try just one, replace the queue = ... with:

    static dispatch_once_t once;
    static dispatch_queue_t queue = NULL;
    dispatch_once(&once, ^{
        queue = dispatch_queue_create("com.blah.url-fetch", NULL);
    });
    

    Leave the rest of the code as is. This is likely to be the least sputtery, but may not load the images very fast.

    For the more general case, rip out the change I just gave you, and we will work on this:

    dispatch_async(queue, ^{
        UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:url]];
        dispatch_async(dispatch_get_main_queue(), ^{
            [self writeImageData:UIImagePNGRepresentation(image) toFilePath:filePathForURL(url)];
            _block(image);
        });
    });
    

    Replacing it with:

    static dispatch_once_t once;
    static const int max_in_flight = 2;  // Also try 4, 8, and maybe some other numbers
    static dispatch_semaphore_t limit = NULL;
    dispatch_once(&once, ^{
        limit = dispatch_semaphore_create(max_in_flight);
    });
    dispatch_async(queue, ^{
        dispatch_semaphore_wait(limit, DISPATCH_TIME_FOREVER);
        UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:url]];
        //  (or you might want the dispatch_semaphore_signal here, and not below)
        dispatch_async(dispatch_get_main_queue(), ^{
            [self writeImageData:UIImagePNGRepresentation(image) toFilePath:filePathForURL(url)];
            _block(image);
            dispatch_semaphore_signal(limit);
        });
    });
    

    NOTE: I haven’t tested any of this code, even to see if it compiles. As written it will only allow 2 threads to be executing the bulk of the code in your two nested blocks. You might want to move the dispatch_semaphore_signal up to the commented line. That will limit you to two fetches/image creates, but they will be allowed to overlap with writing the image data to a file and calling your _block callback.

    BTW you do a lot of file I/O which is faster on flash then any disk ever was, but if you are still looking for performance wins that might be another place to attack. For example maybe keeping the UIImage around in memory until you get a low memory warning and only then writing them to disk.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

So I have a nicely working UITableView consisting of 3 rows (each including and
I have a UITableView that displays single large images in each cell. The names
I have a uitableview that loads fairly large images in each cell and the
I have a UITableView with pagingEnabled. Each cell takes up the viewing area of
I have a UITableView consisting of three rows - each row is a data
i have uitableview within uitableview (in its cell, like pulse app), and for some
I have a UITableView cell that is going to have a variable size depending
I have a UITableview made up with a custom cell loaded from a nib.
I have UITableView with cells. Cell contains image, label and detail label. Then I've
I have UItableview where every cell containing 5 cell and these cell are representing

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.