0

Instrumentsアプリケーションを使用して、アプリケーションのリークをチェックしています。特定の状況下で、HUD パネルのテーブル ビューが 1 秒に 1 回更新されます。毎秒 (reloadData) _NSArrayl オブジェクトの数が 1 ずつ増えることを除いて、すべて正常に動作しています。データソースを単なる return(@""); に変更すると (それらはすべてテキストセルです)、問題は残ります(変化なし)。周囲のコードをすべて削除すると、次のようになります。

[myTableView reloadData];

- (id)tableView:(NSTableView *)tv objectValueForTableColumn:(NSTableColumn *)column row:(int)rowIndex {
   return(@"");
}

(またはnilを返すことさえあります)

問題は解決しません。[myTableView reloadData] をコメントアウトすると、問題は解決します。各ブロックは _NSarrayl で、サイズは 32 バイトで、詳細は次のとおりです。

   0 libsystem_c.dylib calloc
   1 libobjc.A.dylib class_createInstance
   2 CoreFoundation __CFAllocateObject2
   3 CoreFoundation +[__NSArrayI __new::]
   4 CoreFoundation -[__NSPlaceholderArray initWithObjects:count:]
   5 CoreFoundation +[NSArray arrayWithObjects:]
   6 AppKit -[NSWindow _runLoopModesForInvalidCursorRectsObserver]
   7 AppKit __-[NSWindow _postInvalidCursorRects]_block_invoke_1
   8 CoreFoundation __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__
   9 CoreFoundation __CFRunLoopDoObservers
  10 CoreFoundation __CFRunLoopRun
  11 CoreFoundation CFRunLoopRunSpecific
  12 HIToolbox RunCurrentEventLoopInMode
  13 HIToolbox ReceiveNextEventCommon
  14 HIToolbox BlockUntilNextEventMatchingListInMode
  15 AppKit _DPSNextEvent
  16 AppKit -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:]
  17 AppKit -[NSApplication run]
  18 AppKit NSApplicationMain

これらのオブジェクトの履歴に Autorelease エントリがあることに気付いたので、自動解放されたのではないかと思います (保持カウントはまだ 1 です)。しかし、5 分以上経っても何も解放されていないため、自動解放プールが解放されていない可能性があります。自動解放プールは作成せず (また解放もせず)、アプリケーション フレームワークのままにします。自動解放プールで何かをする必要がありますか?

#   Address Category    Event Type  RefCt   Timestamp   Size    Responsible Library Responsible Caller
0   0x100669cf0 __NSArrayI  Malloc  1   00:01.342.634   32  AppKit  -[NSWindow _runLoopModesForInvalidCursorRectsObserver]
1   0x100669cf0 __NSArrayI  Autorelease <null>  00:01.342.636   0   AppKit  -[NSWindow _runLoopModesForInvalidCursorRectsObserver]

私が間違っているかもしれないことについての提案は非常に高く評価されます。

1 秒の更新の状況はアプリケーションの「通常の状況」ではありませんが、発生する可能性があり、アプリケーションは長期間にわたって設計されていることに注意してください。つまり、実行、終了、再実行、終了などのアプリケーションではありません。

それらは「リーク」として検出されていませんが、割り当て数は永遠に増加し続けているため、実際にはリークであると想定しています(または何か問題が発生しています)。

私は「ガベージコレクション」ではなくARCを使用していません-保持/解放システムだけであり、保持/解放を使用する傾向があり、自分のコードは時々自動解放を使用するだけで、このコードとは関係ありません。

追加情報: 私は、Instruments アプリケーションのみを使用して、カウントが増加するのを座って見ていました (テーブルビューは、常に表示される HUD にあります)。ただし、たとえば「漏れやすい」テーブルビューの上にマウスを移動すると、カウントは妥当なものに戻ります。テーブルビューを含む HUD ウィンドウを画面上で少し移動すると、カウントが元に戻ります。これは、ユーザー アクティビティが不足しているためと思われます。私はまだ困惑していますが、この新しい観察がアイデアの助けになるかもしれないと思いました (または誰かがそれを再現しようとした場合)。

4

2 に答える 2

1

コード自体は漏れません。しかし、何が起こるかというと、外側の自動解放プールが空にならないということです。これは AppKit では注意が必要です。AppKit の実行ループは自動解放プールを自動的に追加しますが、イベントを受信したとき (つまり、マウスを動かしたとき) にのみプールを排出します。

アプリを起動してマウスを動かし、リークを再試行することで確認できます。

これは、一般に、カスタムの非イベント ドリブン コールバックに独自の自動解放プールを追加することをお勧めすることを意味します。いくつかの基本的な Foundation メカニズムはすでにそれを行っています (たとえば、NSTimer は発火前にプールを作成し、後でそれを排出します) が、すべてがそれを行うわけではありません。

この特定のケースでは、その特定のコールバックをあまり制御できないようです。

1)リークを実行する前に、アプリケーションをくすぐることを考えてください

2) Apple にバグを報告するかもしれません

于 2012-08-08T23:43:03.947 に答える