UIScrollView のページとして機能する複数の UIView サブクラスを持つアプリがあります。UIView は前後に移動して、ユーザーにシームレスなエクスペリエンスを提供します。ビューのコンテンツは描画がかなり遅いため、NSOperation サブクラスによるロックによって保護された単一の共有 CGBitmapContext でレンダリングされます - NSOperationQueue で一度に 1 つずつ実行されます - UIImage にラップされ、コンテンツを更新するためにメイン スレッドによって使用されますビューの。
-(void)main {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc]init];
if([self isCancelled]) {
return;
}
if(nil == data) {
return;
}
// Buffer is the shared instance of a CG Bitmap Context wrapper class
// data is a dictionary
CGImageRef img = [buffer imageCreateWithData:data];
UIImage * image = [[UIImage alloc]initWithCGImage:img];
CGImageRelease(img);
if([self isCancelled]) {
[image release];
return;
}
NSDictionary * result = [[NSDictionary alloc]initWithObjectsAndKeys:image,@"image",id,@"id",nil];
// target is the instance of the UIView subclass that will use
// the image
[target performSelectorOnMainThread:@selector(updateContentWithData:) withObject:result waitUntilDone:NO];
[result release];
[image release];
[pool release];
}
メイン スレッドで実行される UIView サブクラスの updateContentWithData: も同様に単純です。
-(void)updateContentWithData:(NSDictionary *)someData {
NSDictionary * data = [someData retain];
if([[data valueForKey:@"id"]isEqualToString:[self pendingRequestId]]) {
UIImage * image = [data valueForKey:@"image"];
[self setCurrentImage:image];
[self setNeedsDisplay];
}
// If the image has not been retained, it should be released together
// with the dictionary retaining it
[data release];
}
サブクラスの drawLayer:inContext: メソッドは、UIImage から CGImage を取得し、それを使用してバッキング レイヤーまたはその一部を更新します。このプロセスには保持または解放は含まれません。
問題は、しばらくするとメモリが不足することです。UIView の数は静的です。CGImageRef と UIImage は正しく作成、保持、およびリリースされます (またはそう思われます)。インスツルメントにはリークは見られません。使用可能な空きメモリが常に低下し、数回上昇してから、アプリケーションが終了するまでさらに低下します。アプリはその前に前述のページの約 2 ~ 300 を循環しますが、大量のページが既に高速でスキミングされた後、または、画像のサイズは最大 3MB で、かなり早い段階で枯渇します。
どんな提案でも大歓迎です。