ios - 下载多个文件时如何避免内存警告

标签 ios objective-c grand-central-dispatch

我正在下载多个这样的文件

ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];

HUD = [[MBProgressHUD alloc] initWithWindow:self.view.window];
HUD.labelText = @"Downloading";
HUD.mode = MBProgressHUDModeIndeterminate;
[self.view.window addSubview:HUD];
[HUD show:YES];

dispatch_group_t group = dispatch_group_create();
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH,0);

for (NSString *urlString in URLStrings) {
    dispatch_group_async(group, queue, ^{
        NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:urlString]];
        UIImage *image = [[UIImage alloc] initWithData:data];
        [library writeImageToSavedPhotosAlbum:[image CGImage] orientation:(ALAssetOrientation)[image imageOrientation] completionBlock:^(NSURL *assetURL, NSError *error) {


        }];
    });
}

dispatch_group_notify(group, queue, ^{
    dispatch_async(dispatch_get_main_queue(), ^{
        HUD.mode = MBProgressHUDModeText;
        HUD.labelText = @"Success";
        [self performSelector:@selector(hideHUDAndBack) withObject:Nil afterDelay:0.3];
    });
});

dispatch_release(group);

当下载总大小为 20MB 或更大的文件时,它会收到内存警告并关闭。我尝试在主线程上没有 gcd 的情况下运行它,但它仍然在最后收到内存警告并关闭。主要原因是什么以及如何解决?

最佳答案

在您的方法中,我看不到使用分派(dispatch)库来并行化网络请求有任何优势。通过多个并发网络请求可以实现的是减少网络延迟的影响。但是,您的简单方法同时引入了内存问题。

在给定的场景中,从远程服务器加载视频,我们可以假设文件非常大,因此延迟成为一个小问题。主导因素是带宽。但是,当带宽成为限制因素时,一次加载多个视频无法更快地加载视频。

因此,我建议您尝试以下更简单的解决方案:

for (NSString *urlString in URLStrings) {
    @autoreleasepool {
        NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:urlString]];
        UIImage *image = [[UIImage alloc] initWithData:data];
        [library writeImageToSavedPhotosAlbum:[image CGImage] orientation:(ALAssetOrientation)[image imageOrientation] completionBlock:^(NSURL *assetURL, NSError *error) {
            // HUD.infoText = @"Saved asset %@, assetURL";
        }];
    }
}
HUD.mode = MBProgressHUDModeText;
HUD.labelText = @"Download complete";
[self performSelector:@selector(hideHUDAndBack) withObject:Nil afterDelay:0.3];

注意:由于下载资源是顺序和同步的,你应该将这些语句包装成一个 block 并使用dispatch_async,以便在辅助线程上执行它(即不在主线程上)线程)。

您现在应该改进的是下载视频的方式。 dataWithContentsOfURL: 方法最不适合加载远程资源。 ;)

关于ios - 下载多个文件时如何避免内存警告,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20235783/

相关文章:

iOS iPad 开发设计决策

ios - 测试定义为 Any 的值的数组包含,但保证属于同一类型。

objective-c - 将 NSString 添加到可变数组

iOS:Grand Central Dispatch 和 ViewController

ios - NSOperation 没有在后台线程中发生

ios - 使用适用于 iOS 的 Dropbox API 计算文件大小

iphone - 在运行同一应用程序的两个 iOS 设备之间传输对象的最佳方式是什么?

objective-c - addSubview 没有出现在 NSView Objective C Cocoa 中

ios - CGPDFDictionaryGetString 函数 nil 参数异常

objective-c - Grand Central Dispatch 的简单示例