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

  • SEARCH
  • Home
  • 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 8322095
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 8, 20262026-06-08T23:15:43+00:00 2026-06-08T23:15:43+00:00

I have an app which downloads some files from the server in few threads.

  • 0

I have an app which downloads some files from the server in few threads. The problems is that it is giving a heavy load to the CPU (hitting to 80%). What can be done to make it better? I made similar app on Windows with C#, and the cpu usage never goes above 5%.

EDIT: This code has been changed after getting some suggestions below. The problem now is, that the download never reaches 100% when I set [queue setMaxConcurrentOperationCount:6]. If I change the asynchronous NSURLConnection back to sendSynchronous call it works, when I change the above OperationCount to 1, also works.

This is how I add NSOperations to the queue (may be large, like 800).

int chunkId = 0;
for (DownloadFile *downloadFile in [download filesInTheDownload])
{
    chunkId = 0;
    for (DownloadChunk *downloadChunk in [downloadFile chunksInTheFile])
    {
        DownloadChunkOperation *operation = [[DownloadChunkOperation alloc]  initWithDownloadObject:download
      downloadFile:downloadFile                                                                                                    downloadChunk:downloadChunk                                                                                                           andChunkId:chunkId];
    [queue addOperation:operation];
    chunkId++;
    }
}


#import "DownloadChunkOperation.h"
#import "Download.h"
#import "DownloadFile.h"
#import "DownloadChunk.h"

@interface DownloadChunkOperation()
@property(assign) BOOL isExecuting;
@property(assign) BOOL isFinished;
@end

@implementation DownloadChunkOperation

@synthesize download = _download;
@synthesize downloadFile = _downloadFile;
@synthesize downloadChunk = _downloadChunk;

@synthesize isFinished = _isFinished;
@synthesize isExecuting = _isExecuting;

- (id) initWithDownloadObject:(Download *)download downloadFile:(DownloadFile *)downloadFile downloadChunk:(DownloadChunk *)downloadChunk andChunkId:(uint32_t)chunkId
{
    self = [super init];

    if (self) {
        self.download = download;
        self.downloadFile = downloadFile;
        self.downloadChunk = downloadChunk;
        self.chunkId = chunkId;
    }

    return self;
}

- (void) start
{
    if ([self isCancelled]) {
        [self setIsFinished:YES];
        [self setIsExecuting:NO];
        return;
    }

    [self setIsExecuting:YES];
    [self setIsFinished:NO];
    [self.downloadChunk setChunkState:cDownloading];

    downloadPath = [[NSString stringWithFormat:@"%@/%@", [self.download downloadFolder], [self.download escapedTitle]] stringByExpandingTildeInPath];

    NSURL *fileURL = [[NSURL alloc] initWithString:[self.downloadFile filePath]];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:fileURL];
    NSString *range = [NSString stringWithFormat:@"bytes=%lli-%lli", [self.downloadChunk startingByte], [self.downloadChunk endingByte]];
    [request setValue:range forHTTPHeaderField:@"Range"];
    connection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:NO];
    // IMPORTANT! The next line is what keeps the NSOperation alive for the during of the NSURLConnection!
    [connection scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    [connection start];

    if (connection) {
        NSLog(@"connection established!");
        do {
            [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
        } while (!self.isFinished);
    } else {
        NSLog(@"couldn't establish connection for: %@", fileURL);
    }
}

- (BOOL) isConcurrent
{
    return YES;
}

- (void) connection:(NSURLConnection *)_connection didReceiveResponse:(NSURLResponse *)response
{
    receivedData = [[NSMutableData alloc] init];
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    // Not cancelled, receive data.
    if (![self isCancelled]) {
        [receivedData appendData:data];
        self.download.downloadedBytes += [data length];
        return;
    }

    // Cancelled, tear down connection.
    [self setIsExecuting:NO];
    [self setIsFinished:YES];
    [self.downloadChunk setChunkState:cConnecting];
    [self->connection cancel];
}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
    [self setIsExecuting:NO];
    [self setIsFinished:YES];
    NSLog(@"Connection failed! Error - %@ %@",
          [error localizedDescription],
          [[error userInfo] objectForKey:NSURLErrorFailingURLStringErrorKey]);
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    NSString *chunkPath = [downloadPath stringByAppendingFormat:@"/%@.%i", [self.downloadFile fileName], self.chunkId];
    NSError *saveError = nil;
    [receivedData writeToFile:chunkPath options:NSDataWritingAtomic error:&saveError];
    if (saveError != nil) {
        NSLog(@"Download save failed! Error: %@", [saveError description]);
    }
    else {
        NSLog(@"file has been saved!: %@", chunkPath);
    }
    [self setIsExecuting:NO];
    [self setIsFinished:YES];
    [self.downloadChunk setChunkState:cFinished];

    if ([self.download downloadedBytes] == [self.download size])
        [[NSNotificationCenter defaultCenter] postNotificationName:@"downloadFinished" object:self.download];
}

@end
  • 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-06-08T23:15:45+00:00Added an answer on June 8, 2026 at 11:15 pm

    You should not create threads yourself. Use dedicated API like NSOperationQueue or even GCD directly for this purpose. They know better about hardware limits, virtual cores, etc. and support priority settings.

    You shouldn’t use +sendSynchronousRequest: either. Wrapping your -downloadChunk method in a dispatch call as suggested by charith won’t help you improve performance, as +sendSynchronousRequest: blocks the thread until new data comes in and forces GCD to spawn new threads.

    Use the asynchronous API of NSURLConnection using delegate callbacks. You can also wrap your NSURLConnection code inside a NSOperation subclass and use NSOperationQueue to manage the downloads: Using NSURLConnections

    If you don’t want to write the NSOperation subclass yourself, you can also use a 3rd party framework like AFNetworking.

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

Sidebar

Related Questions

I have an app, which needs to download some files from server and use
I have some code that downloads a plist from a web server and stores
I have app in which i have recorded sound files i want that i
I am trying to program an App that fetches files from a server. I
I am coding an app that give me some problems. I have an activity
I have a small Silverlight app which downloads all of the images and text
I have a little Updater in my mac app, which automatically downloads a dmg-file
I have a paid application on the App Store, which when a user downloads,
I have a app which will download a file from web. The download action
I have an app which has a map and some POI on it. I'm

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.