アクセサリに接続するアプリがあり、アクセサリを切断すると、アクセサリと通信するために作成した EASession がリークします。
アクセサリが接続されると、これに関する通知を受け取り、EAAccessoryManager のアクセサリ コレクションをチェックして、特定のプロトコルを使用する特定の名前のアクセサリを探します。これを見つけたら、そのアクセサリの EASession オブジェクトをコードで作成します。
-(void) openSession
{
... // finds accessory object
if (accessory)
{
[self closeSession];
session = [EASession alloc];
NSLog(@"alloc :: session retainCount: %i", session.retainCount);
[session initWithAccessory:accessory forProtocol:SmokeSignalsProtocolName];
NSLog(@"init :: session retainCount: %i", session.retainCount);
[[session inputStream] open];
[[session outputStream] open];
... // other logic (pump run loop, etc..)
}
}
-(void) closeSession
{
if (session)
{
[[session inputStream] close];
[[session outputStream] close];
[session release], session = nil;
}
}
通常、私は alloc と init を 1 行に持っていますが、(このように分離して) 見つけたのは、alloc が +1 の保持カウントを与えることです (ご想像のとおり) iniWithAccessory:forProtocol:
。 init メソッドからの +2 の保持カウントのみを期待します。
リークインストゥルメントもこれをサポートしているようです。
リーク計測器を段階的に見ていきます。
- +1 保持カウント ::
[???Accessory openSession]
- これは、新しい EASession を割り当てる場所です。 - +1 保持カウント ::
[EAInputStream iniWithAccessory:forSession:]
入力ストリームは、所有しているセッションへの参照を保持します。 - +1 保持カウント ::
[EAOutputStream initWithAccessory:forSession:]
出力ストリームは、所有しているセッションへの参照を保持します。 - +1 保持数 ::
[EASession iniWithAccessory:forProtocol:]
これが EASession の保持数を増やしている理由がわかりません。これは、説明できない追加の保持カウントの原因であると思います...これがどのようにバランスが取れているのかわかりません。これは Apple のバグなのかrelease
、バランスをとるために余分な時間を費やす必要があります.... 非常に奇妙です。 - -1 保持カウント ::
[EAInputStream close]
上記のステップ #2 をクリーンアップします - -1 カウントを保持 ::
[EAOutputStream close]
上記のステップ #3 をクリーンアップします - -1 カウントを保持 ::
???Accessory closeSession]
上記のステップ #1 をクリーンアップします1
だから...なぜ私はEASessionオブジェクトを漏らしているのですか? リークしないために EASession オブジェクトを使用する適切な方法は何ですか?
編集 - EADemo はリークしませんが ...
EADemoはアクセサリーに接続しますが漏れません。好奇心から[_session retain]
、インストゥルメントで malloc の履歴をたどることができるように、リークを発生させるエクストラを追加しました。私のアプリの malloc 履歴で呼び出されなかったいくつかの内部的なものを見るのは興味深いことでした。
[EAAccessoryInternal removeSession:]
これが3 回呼び出されたことがわかります。これは、アプリの malloc 履歴で呼び出されたことはありません。これが、私の EASession がリリースされない理由の鍵だと思います...