调度中的内存管理

时间:2012-11-04 18:33:24

标签: ios memory-management dispatch

我尝试使用以下代码在后台所有视图的iPad应用程序上竖起大拇指:

NSString *path = [self.page previewPathForOrientation:currentOrientation];
dispatch_async( dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
  @autoreleasepool {
    UIGraphicsBeginImageContextWithOptions(self.previewView.bounds.size, NO, 0.0);
    [self.previewView.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    self.previewView = nil;
    float scale = [UIScreen mainScreen].scale;
    CGRect previewRect = currentOrientation == Landscape ? [[OrientationLandscape singleton] frameForPreviewImage] : [[OrientationPortrait singleton] frameForPreviewImage];
    CGSize previewSize = CGSizeMake(previewRect.size.width * scale, previewRect.size.height * scale);
    UIImage *scaledImage = [image scaleImageToSize:previewSize];

    CGImageDestinationRef imageDestination = CGImageDestinationCreateWithURL((__bridge CFURLRef)[[NSURL alloc] initFileURLWithPath:path], (__bridge CFStringRef)@"public.png", 1, NULL);
    CGImageDestinationAddImage(imageDestination, [scaledImage CGImage], NULL);
    CGImageDestinationFinalize(imageDestination);
    CFRelease(imageDestination);

    NSFileManager *fileMngr = [[NSFileManager alloc] init];
    if(![fileMngr fileExistsAtPath:path])
    {
      ZAssert(0, @"could not save preview file");
    }
    dispatch_async(dispatch_get_main_queue(), ^{
      rendered++;
      //DLog(@"rendered %d items", rendered);
      [GetController addSkipBackupAttributeToItemAtPath:path];
      [self.page setPreviewRenderedForOrientation:currentOrientation];
      contentsCount = 0;
      currentContentIndex = 0;
      //[self prepareOtherOrientation];
      if(self.journal == nil && (![self.page previewRenderedForOrientation:Landscape] || ![self.page previewRenderedForOrientation:Portrait])){
        [self appendPage:self.page];
      }
      DLog(@"rendered page %@ in orientation %d", self.page, currentOrientation);
      self.page = nil;
      [self retry];
    });
  }
});

重试功能使用NSTimer在短暂延迟和不同页面后再次启动相同的功能。使用Allocations工具,堆只会不断增长。在应用程序崩溃后不久,我会在一段时间内收到内存警告。

当我删除所有调度电话时,一切正常,但当然这不是我想要的。此外,当我将重试方法的延迟增加到5秒时,问题也会消失,所以当事情快速连续处理时,似乎内存不会被释放。

我绝对确保这种方法一次不会运行多次......任何想法在这里发生了什么?

0 个答案:

没有答案