0

NSThreadそのため、ループ内で多数の s を作成するコードを で実行していますNSImage。各画像の小さなセクションが別の に描画されNSImage、スレッドが終了します。

だから、次のようなもの

NSImage *outputImage = [[NSImage alloc] initWithSize:size];
[outputImage lockFocus];
while(1000 times)
    NSImage* image = [[NSImage alloc] initWithSize:size];
    ... image is processed ...
    [image drawInRect: ... fromRect: ... ]
[outputImage unlockFocus];

これが完了すると、スレッドはperformSelectorOnMainThread作成された NSImage をメイン スレッドに送り返し、ビューに配置します。

これはすべて正常に機能し、最終的な画像はまさに期待どおりです。ただし、ループ中、アプリケーションのメモリ使用量は直線的に増加します。あたかもそれぞれNSImageが後で解放されるかのように。私の理論では、drawInRect呼び出しはどこかでパイプライン処理されており、実際には実行されるのは後であるというものです。これは正しいです?もしそうなら、どうすればそれを防ぐことができますか?現時点でループ カウンターを大きくしすぎると、アプリケーションがクラッシュするので、それは避けたいと思います。

フォーカスのロックとロック解除をループに移動しようとしましたが、違いはありませんでした。

呼び出しだけを行うdrawInRectと、スレッドの存続期間中、メモリ使用量が (多かれ少なかれ) フラットであることを確認しました。メモリが上がるのは、電話をかけたときだけです。

私は (明らかに?) このプロジェクトで ARC を使用しており、OSX10.9 で実行されています。

4

1 に答える 1

2

ある時点で NSImages が自動解放プールに追加されているようです。通常、プールが空になるまでフラッシュされません。

このような場合は、独自の autorelease プールを作成します。

NSImage *outputImage = [[NSImage alloc] initWithSize:size];
[outputImage lockFocus];
while(1000 times) {
    @autoreleasepool {
        NSImage* image = [[NSImage alloc] initWithSize:size];
        ... image is processed ...
        [image drawInRect: ... fromRect: ... ]
    }
}
[outputImage unlockFocus];

これにより、パスごとに排出されるサブプールが作成されるため、イメージが大量に蓄積されることはありません。

于 2014-01-22T00:17:47.867 に答える