崩溃与NSOperations中的大型成功关联(内存问题)

时间:2014-03-04 08:30:30

标签: ios objective-c memory-management core-graphics

我有UICollectionView。在每个单元格显示时,我正在尝试缓存图像。首先我下载它,然后我将它保存在光盘上(后来我从光盘读取,但现在这已被注释以简化案例。为了确保它没有导致问题,我已经测试了泄漏/分配工具)。

所以在每个单元格中,我使用successBlock调用方法。

// inside collectionView:cellForItemAtIndexPath:
[self imageForObject:myObject withCompletionBlock:myCompletitionBlock];

然后我正在创建NSOperation并将其添加到队列中(使用maxConcurrentOperationCount == 5

NSOperation *operation = [self fetchImageWithProperties:propertiesHere 
                                        processingBlock:processingBlock 
                                                success:success 
                                                failure:failure];
[_myQueue addOperation:operation];

在方法fetchImage中,我使用AFNetworking(1.3.3,现在将它更改为2.2的时间太多)方法:

imageRequestOperationWithRequest:imageProcessingBlock:success:failure:

successBlock上的图像将图像保存到光盘(下面粘贴的方法)。这里产生了问题。当我快速刷扫细胞时,我的记忆力可以跳得这么高,应用程序会崩溃。后来它正在下降。我可以通过注释掉CGImageDestination..方法来摆脱这个问题,但是由于图像没有被保存,所以整个缓存的想法没有意义。

CGImageDestinationRef idst = 
  CGImageDestinationCreateWithURL((__bridge CFURLRef)myUrl, 
                                  (__bridge CFStringRef)myImageType, 
                                  1, 
                                  (__bridge CFDictionaryRef)options);
if (imageDest != NULL) {
     // if i comment out following 2 methods, memory do not increase
     CGImageDestinationAddImage(idst, 
                                myImageCgImageRef, 
                                (__bridge CFDictionaryRef)myOptions);
     CGImageDestinationFinalize(idst);
     CFRelease(idst);
}

我还必须补充一点,在方法collectionView:didEndDisplayingCell:forItemAtIndexPath:中,我正在从单元格中取消操作。

什么会导致内存问题?

顺便说一句:可能有些令人惊讶,_myQueue.operations.count有时约为7。

2 个答案:

答案 0 :(得分:0)

CFRelease(idst)条件之外调用此方法if。因为如果它被创建,你负责这个版本。这可能会导致内存问题。

CGImageDestinationRef idst = CGImageDestinationCreateWithURL((__bridge CFURLRef)myUrl, (__bridge CFStringRef)myImageType, 1, (__bridge CFDictionaryRef)options);
 if (imageDest != NULL) {
      // if i comment out following 2 methods, memory do not increase
      CGImageDestinationAddImage(idst, myImageCgImageRef, (__bridge CFDictionaryRef)myOptions);
      CGImageDestinationFinalize(idst);
 }
CFRelease(idst);

答案 1 :(得分:0)

因为你说,当应用程序没有崩溃时,内存在峰值后降至正常水平,我们可以排除内存泄漏或放弃内存作为崩溃的根本原因。

此类情况下的一个重要资源是内存警告。在崩溃之前你一定会得到一系列的。您应该尝试释放在内存警告处理程序中分配的尽可能多的资源。要查看内存累积的位置,请在执行图像处理步骤(仪器/分配工具/生命和死亡对象)时尝试获取应用程序的内存快照。

除此之外,我会尝试不同的方法将图像保存到文件中:

NSData *imgData = UIImageJPEGRepresentation(image, 1);
//-- alternatively:    NSData *imgData = UIImagePNGRepresentation(image);
[imgData writeToFile:filePath atomically:YES]; 

以防万一内存效率高于CGImageDestination

另外,您还可以尝试重新启动设备,看看新鲜内存会发生什么。 iOS设备往往处于一种状态,几乎任何任务都可能因内存压力而导致崩溃。