【问题标题】:downloading large amount of images ipad - memory leak?下载大量图像 ipad - 内存泄漏?
【发布时间】:2011-05-30 04:18:27
【问题描述】:

我正在编写一个应用程序,它需要下载大量图像,可能是 10,000 个。现在我可以在内存不足和应用程序崩溃之前达到大约 3000,这取决于图像文件的大小。我正在后台线程上下载它们并向用户显示进度。

我编写了一个辅助类,我正在访问它来执行此操作,并想知道这是否是我的问题所在,我只是在泄漏内存。

这是我下载图像的循环 - 这是在后台线程上运行的,这都在 NSAutoReleasePool 中:

for (int j=0; j < [items count]; j++)
            {

                ImagesHelper *helper = [[ImagesHelper alloc]init];
                [helper downloadImages: [[items objectAtIndex:j] valueForKey:@"ItemSKU"] withManufacturer: [[manufacturers objectAtIndex:i] ManufacturerID]];
                [helper release];

                if (j%50==0) { //this notifies the user of progress
                    statusMessage = [NSString stringWithFormat:@"Downloading images: %@.jpg (%d of %d)", [[items objectAtIndex:j] valueForKey:@"ItemSKU"],j+1, [items count]];
                    [self performSelectorOnMainThread:@selector(setStatus) withObject:nil waitUntilDone:YES];
                }
            }

这是我的助手类:

-(void) downloadImages:(NSString *)ItemSKU withManufacturer: (NSString *) aManufacturerID{

    NSData *imageData = nil;
    NSData *imageDataLarge=nil;
    NSString *fileName = [NSString stringWithFormat:@"%@_tn.jpg", [ItemSKU  stringByReplacingOccurrencesOfString:@" " withString:@""]];
    NSString *fileNameLarge = [NSString stringWithFormat:@"%@_lg.jpg", [ItemSKU stringByReplacingOccurrencesOfString:@" " withString:@""]];

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsPath = [paths objectAtIndex:0];
    NSString *savePath = [documentsPath stringByAppendingPathComponent:fileName];
    NSString *savePathLarge = [documentsPath stringByAppendingPathComponent:fileNameLarge];

    /* go get the image */
    NSString *URL = [NSString stringWithFormat:kProductImagesURL,aManufacturerID, fileName];
    NSString *URLLarge = [NSString stringWithFormat:kProductImagesURL,aManufacturerID, fileNameLarge];

    NSLog(@"Going to get the file: %@",URL);
    imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:URL]];
    if (imageData!=nil) {
        [imageData writeToFile:savePath atomically:YES];
    }

    imageDataLarge = [NSData dataWithContentsOfURL:[NSURL URLWithString:URLLarge]];
    if (imageDataLarge!=nil) {
        [imageDataLarge writeToFile:savePathLarge atomically:YES];
    }

    imageData = nil;
    imageDataLarge=nil;
}

仍在尝试掌握其中一些概念。

【问题讨论】:

    标签: iphone objective-c ipad


    【解决方案1】:

    您是否尝试过构建和分析?这可能会有所帮助。还可以玩乐器。最后,我建议对这些使用 NSOperationQueue。这样你就可以并行执行它们。此外,在控制权返回到主线程之前,您的 AutoReleasePool 可能不会自动释放任何内容。

    【讨论】:

    • 是的,看起来在我回到主线程后,一切都被释放了。我必须将它们分成小块并运行一系列后台线程。
    • +1 表示操作队列。它是为这样的东西而构建的。
    【解决方案2】:

    您使用的每个工厂方法(stringWith*、stringBy*、URLwith*、dataWith* 等)都返回一个自动释放的对象,该对象的池在循环结束之前不会为空。在这些东西上尝试alloc init,然后在完成后立即尝试release。您应该会看到更好的结果。

    【讨论】:

      【解决方案3】:

      戴夫说得对……使用NSInvocationOperation。 tht 将解决问题,而不是将代码分成块。这是我使用的示例

      NSOperationQueue *downloadQueue = [NSOperationQueue new];
      for (Product *cProduct in productsMasterArray) 
      {                   
           NSInvocationOperation *downloadOperation = [[NSInvocationOperation alloc] 
                                                                  initWithTarget:self             selector:@selector(downloadImages:) 
                                                              object:cProduct.ITEM_CODE];
                      [downloadQueue addOperation:downloadOperation];
                      [downloadOperation release];
                  }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-01-14
        • 1970-01-01
        • 1970-01-01
        • 2017-01-27
        • 2016-08-10
        • 1970-01-01
        相关资源
        最近更新 更多