Reputation: 44730
I noticed that the framerate while scrolling a collection view on an iPhone 4 dropped significantly (at times to 5 FPS) when a download using NSURLConnection was taking place in the background. I first suspected AFNetworking to be the culprit, but it turns out that the same thing happens when I simply use a block:
- (void)startBlockDownload:(id)sender
{
NSLog(@"starting block download");
dispatch_queue_t defQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
void (^downloadBlock) (void);
downloadBlock = ^{
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:_urlString]];
NSURLResponse *response = nil;
NSError *error = nil;
NSData* result = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
NSLog(@"block request done");
};
dispatch_async(defQueue, downloadBlock);
}
What gives? Is a background download so demanding that it renders the UI extremely sluggish? Is it the slow flash memory? Is there anything that can be done to keep the UI very responsive while doing a background download?
I've created a sample project to demonstrate the issue: https://github.com/jfahrenkrug/AFNetworkingPerformanceTest
Also see this issue on AFNetworking that I have started about the topic: https://github.com/AFNetworking/AFNetworking/issues/1030#issuecomment-18563005
Any help is appreciated!
Upvotes: 1
Views: 511
Reputation: 33421
As the comments you linked to say: The iPhone 4 is still a single-core machine so no matter how much "multitasking" you do, it will still only be executing one set of code at once. What's worse is that the sendSynchronousRequest and the UI code are both blocking sets of code, so they will take up the maximum amount of time allotted to them by the OS and then the OS will perform an expensive context switch to prepare to execute the other.
You can try two things:
1) Use the async API of NSURLConnection
instead of dispatching away a synch request (though I have the feeling you tried this with AFNetworking
).
2) Lower the priority of the queue you dispatch to (preferably to DISPATCH_QUEUE_PRIORITY_BACKGROUND if possible). This might give the main queue more cycles to execute on, but it may not since the entire operation is just one big chunk.
If those both fail to work, then it probably simply is too much for a single-core processor to handle (scrolling is not a light operation, and downloading requires constant running time to receive data). That's my best guess anyway...
Upvotes: 2