我有当前的代码,可以为我们的企业应用程序提供一个大文件列表(大约 6k 图像,大约 2.8GB 大小)。
传输文件量约为 1.71GB(约 660 秒)时,内存显然已耗尽。我想知道我可以做些什么来优化:
队列:
dispatch_queue_t imageQueue1 = dispatch_queue_create("Image Queue 1", NULL);
循环:
for (int i = 0; i < [imgs count]; i++) {
dispatch_async(imageQueue1, ^{
NSString *path = [[NSString alloc] initWithFormat:@"%@/%@", damPath, [imgs objectAtIndex:i]];
NSURL *url = [[NSURL alloc] initWithString:path];
NSData *data = [[NSData alloc] initWithContentsOfURL:url];
NSString *savePath = [[NSString alloc] initWithFormat:@"%@/%@", newDir, [imgs objectAtIndex:i]];
if (![data writeToFile:savePath atomically:YES]) {
NSLog(@"Saving of \"%@\" failed!", [imgs objectAtIndex:i]);
}
NSString *progress = [[NSString alloc] initWithFormat:@"%d / %u downloaded...", i, [imgs count]];
NSLog(@"%@", progress);
});
}
我还想知道如何对这些 GCD 队列进行多任务处理。在我的测试中,我只是复制粘贴此代码 6 次,其中 imageQueue#
递增,[imgs count]
是固定偏移量,仅用于测试目的。
更新
盖子呈颚状图案,大约为 38~MB:
最佳答案
尝试使用@autoreleasepool给自动释放的内存一个耗尽的机会:
for (int i = 0; i < [imgs count]; i++) {
dispatch_async(imageQueue1, ^{
@autoreleasepool {
NSString *path = [[NSString alloc] initWithFormat:@"%@/%@", damPath, [imgs objectAtIndex:i]];
NSURL *url = [[NSURL alloc] initWithString:path];
NSData *data = [[NSData alloc] initWithContentsOfURL:url];
NSString *savePath = [[NSString alloc] initWithFormat:@"%@/%@", newDir, [imgs objectAtIndex:i]];
if (![data writeToFile:savePath atomically:YES]) {
NSLog(@"Saving of \"%@\" failed!", [imgs objectAtIndex:i]);
}
NSString *progress = [[NSString alloc] initWithFormat:@"%d / %u downloaded...", i, [imgs count]];
NSLog(@"%@", progress);
}
});
}
查看文档,调度队列确实提供了自动释放池,但不能保证它们会被耗尽,因此对于像这样的内存密集型操作,您可能可以通过添加自己的自动释放池来获得更好的服务。
if your block creates more than a few Objective-C objects, you might want to enclose parts of your block’s code in an @autorelease block to handle the memory management for those objects. Although GCD dispatch queues have their own autorelease pools, they make no guarantees as to when those pools are drained. If your application is memory constrained, creating your own autorelease pool allows you to free up the memory for autoreleased objects at more regular intervals
关于ios - GrandCentralDispatch 大下载队列最终耗尽内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22923523/