谁能回答我,下面的代码怎么会吃掉一个 C2D 2.6GHz CPU 的整个内核?它只下载 10MB 块的文件,可能有 600 个,但 NSOperationQueue 有 6 个并发任务的限制。
为什么在 Windows 上同样的应用程序(用 C# 编写的只吃 2%,而不是 80%!),它只是一个简单的 HTTP 请求!
for (DownloadFile *downloadFile in [download filesInTheDownload])
{
for (DownloadChunk *downloadChunk in [downloadFile chunksInTheFile])
{
NSString *downloadPath = [[NSString stringWithFormat:@"%@/%@", [download downloadFolder], [download escapedTitle]] stringByExpandingTildeInPath];
NSString *chunkPath = [downloadPath stringByAppendingFormat:@"/%@.%i", [downloadFile fileName], [downloadChunk chunkId]];
NSError *attributesError = nil;
NSDictionary *fileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:chunkPath error:&attributesError];
NSNumber *fileSizeNumber = [fileAttributes objectForKey:NSFileSize];
uint64_t fileSize = [fileSizeNumber longLongValue];
NSLog(@"Chunk file size: %lli", fileSize);
uint64_t expectedSize = ([downloadChunk endingByte] - [downloadChunk startingByte]) + 1;
NSLog(@"Chunk expected size: %lli", expectedSize);
uint64_t newStartingByte = [downloadChunk startingByte] + fileSize;
if (fileSize == expectedSize)
{
NSLog(@"Chunk complete: %@.%i", [downloadFile fileName], [downloadChunk chunkId]);
}
else
{
NSURL *fileURL = [[NSURL alloc] initWithString:[downloadFile filePath]];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:fileURL];
NSLog(@"Normal range: %lli-%lli", [downloadChunk startingByte], [downloadChunk endingByte]);
NSString *range = [NSString stringWithFormat:@"bytes=%lli-%lli", newStartingByte, [downloadChunk endingByte]];
[request setValue:range forHTTPHeaderField:@"Range"];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
operation.outputStream = [NSOutputStream outputStreamToFileAtPath:chunkPath append:YES];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(@"%@", [NSString stringWithFormat:@"Chunk complete: %@.%i", [downloadFile fileName], [downloadChunk chunkId]]);
if (download.downloadedBytes == download.size)
[[NSNotificationCenter defaultCenter] postNotificationName:@"downloadFinished" object:download];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"Error: %@", error);
}];
[operation setDownloadProgressBlock:^(NSInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead) {
download.downloadedBytes += bytesRead;
}];
[queue addOperation:operation];
}
}
}
这是一些时间分析器屏幕截图,如果我没看错的话,似乎一切都是因为 RunLoops。