アプリをガベージ コレクションの使用から ARC に変換しました。アプリは ScriptingBridge フレームワークを使用します。好奇心から、Instruments の「Leaks」テンプレートを使用して実行したところ、リークが発生しました。AEDescImpl オブジェクトは私のコードによって直接作成されたものではなく、スクリプト ブリッジによって作成されたようです。私は正しいですか?
これらのリークが ScriptingBridge からのものである場合、これは正常であり、我慢するしかないのでしょうか?
ありがとう。
これは、"Cycles & Roots" -> "Leak Cycles" を示す Instruments の画像です。
関連するセクションに入力しました。
_NSCFアレイ
+40 ( ivar なし ]: AEDescImpl
+56 [ ivar なし ]: AEDescImpl
+64 [ ivar なし ]: AEDescImpl
+72 [ no ivar ]: AEDescImpl
+80 [ ivar なし ]: AEDescImpl
+88 [ ivar なし ]: AEDescImpl
+96 [ ivar なし ]: AEDescImpl
メソッド findOpenTuner を完全に含めることについてのピーターのコメントは、「ミニ」プロジェクトを作成することに拍車をかけました。問題のメソッドは大きく、多くのメソッド呼び出しがあったため、メソッドを本質にまで絞り込みました。メソッドが非常に高速に実行されたため、メソッドを 24 回呼び出す for ループを追加しました。Instruments には何も表示されませんでした。
好奇心から、EyeTVPlayer_window の for ループをコメントアウトし、その上で Instruments を実行しましたが、リークやサイクルは見つかりませんでした。以下に示すように、この for ループのコメントを外すと、リークが発生します。コーディングが正しくないか、Scripting Bridge がリークしているようです。
「ミニ」プロジェクトの実装ファイル。
#import "AppDelegate.h"
#import "EyeTV.h"
@implementation AppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
NSUInteger i;
for (i=0; i<25; i++) {
NSLog(@"before i=%li", i);
[self findOpenTuner];
NSLog(@"after i=%li", i);
}
}
- (void)findOpenTuner;
{
EyeTVApplication *eyeTVApp;
eyeTVApp = [SBApplication applicationWithBundleIdentifier:@"com.elgato.eyetv"]; // 08-04-2011 needed to do mute below in method call filterPlayVolumeMute
SBElementArray *eyeWindows = [eyeTVApp player_windows]; // are EyeTVWindow
BOOL openTunerFound = FALSE; // 07-21-2010
int j=0;
for (EyeTVPlayer_window *eyeWin in eyeWindows) // 12-07-2012 #1
{
if ([[eyeWin programInfo] count] == 0) {
} else {
// this is the tuner we want
openTunerFound = FALSE; // 07-21-2010
[eyeWin select]; // 07-21-2010 // moves "focus" to window, places it at index 0
break; // 07-21-2010 // got the tuner, leave loop
}
j++;
}
}
@end
「ミニ」プロジェクトの楽器のスクリーンショット。