次のコードを使用して、バックグラウンドですべてのビューの 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 ツールを使用すると、ヒープは増え続けます。しばらくすると、アプリがクラッシュした直後にメモリ警告が表示されます。
すべてのディスパッチ呼び出しを削除すると、すべてが正常に機能しますが、もちろんそれは私が望むものではありません。また、retry メソッドの遅延を 5 秒と長くすると、問題も解消されるため、処理が立て続けに行われるとメモリが解放されないようです。
このメソッドが一度に複数回実行されていないことを絶対に確認しました...ここで何が起こっているのでしょうか?