大图像下载循环不断泄漏到GCD队列中

时间:2014-07-08 19:05:05

标签: objective-c memory-management grand-central-dispatch

我正在下载超过6000个高分辨率(约2.6GB),但可以根据哪个客户登录我们的应用程序而更改。由于销售代理需要在国外时加载所有产品图像,因此需要所有产品图像都可以在离线模式下使用。

我的代码几乎是临时的,我的代码泄漏问题对于经验丰富的Objective-C程序员来说可能非常明显。

目前状态是代码已经下载了6253中的2041并且已经过了580秒。然而,模拟器的内存已经达到931MB。

我是否可以采取任何措施来改进此代码,以便在每次循环或X循环周期后恢复内存?

int total_new_images = total_images_in_db - total_images_locally;

// Fetch the real pictures now
dispatch_queue_t imageQueue = dispatch_queue_create("Image Queue", DISPATCH_QUEUE_CONCURRENT);

dispatch_async(imageQueue, ^{
    NSString *path = [NSString new];
    NSURL *url = [NSURL new];
    NSData *data = [NSData new];
    NSString *savePath = [NSString new];
    NSArray *imgUrlArray = [NSArray new];

    NSDate *starTime = [NSDate new];

    @autoreleasepool {
        int c = 0;

        FMResultSet *rs = [self.efashionDB executeQuery:@"SELECT * FROM app_images"];

        while ([rs next]) {
            imgUrlArray = [[rs stringForColumn:@"full_url"] componentsSeparatedByString:@"/"];

            savePath = [NSString stringWithFormat:@"%@/%@", imgFolder, [imgUrlArray objectAtIndex:[imgUrlArray count]-1]];

            if ([self.fileMgr fileExistsAtPath:savePath]) {
                //NSLog(@"'%@' is already saved locally.", [imgUrlArray objectAtIndex:[imgUrlArray count]-1]);
                continue;
            }

            path = [NSString stringWithString:[rs stringForColumn:@"full_url"]];
            url = [NSURL URLWithString:path];
            data = [NSData dataWithContentsOfURL:url];

            if (![data writeToFile:savePath atomically:YES]) {
                NSLog(@"Saving of \"%@\" failed!", [imgUrlArray objectAtIndex:[imgUrlArray count]-1]);
            } else {
                //NSLog(@"Saving of \"%@\" succeeded!", [imgUrlArray objectAtIndex:[imgUrlArray count]-1]);

                // Escape back to the main thread and give status update
                dispatch_async(dispatch_get_main_queue(), ^{
                    NSString *progress = [[NSString alloc] initWithFormat:@"%d of the %d new images downloaded\nTime passed: %d seconds", c, total_new_images, (int)([starTime timeIntervalSinceNow] * -1)];
                    [_imageConsole setText:progress];
                });

                c++; // Only increment if it succeeded
            }

            if (c == 20) {
                //break;
            }
        }
        [rs close];
    }
});

1 个答案:

答案 0 :(得分:2)

尝试在while循环中移动@autoreleasepool。否则,在while循环结束之前,您的分配对象将不会被释放。