ARC の前の時代には、retain と release をオーバーライドして、スタック トレースをログに記録することができました。そうすれば、オブジェクトを保持してはならない場所を簡単に見つけることができました。
現在は禁止されており、インストゥルメントを実行できない場合もあります (たとえば、デバイスでアプリを実行しようとするとすぐにクラッシュし、シミュレーターでバグが再現されません)。
楽器なしでARCでこれを行う方法について何か提案はありますか?
ARC の前の時代には、retain と release をオーバーライドして、スタック トレースをログに記録することができました。そうすれば、オブジェクトを保持してはならない場所を簡単に見つけることができました。
現在は禁止されており、インストゥルメントを実行できない場合もあります (たとえば、デバイスでアプリを実行しようとするとすぐにクラッシュし、シミュレーターでバグが再現されません)。
楽器なしでARCでこれを行う方法について何か提案はありますか?
最終的な答えはないかもしれませんが、正しい方向への一歩である、私が試してみることにしたテクニックを共有します。
ARCを使用すると、コンパイラーはretainCountを要求できなくなり、performSelector:@selector(retainCount)を実行できなくなるほど賢くなります。しかし、私はあきらめず、この便利なデバッグインジケーターにアクセスするためにさらに一歩進んだ。
[anInstance performSelector:NSSelectorFromString(@"retainCount")];
これはコンパイラを通過し、内部でもう少し明らかになります。スタックではありませんが、この値を大量にログに記録することで、いくつかのヒントを得ることができます。
私はおそらくそれをあきらめようとしていますが、スタックを取得するためにさらにトリッキーな(読み:醜い)テクニックで遊んでいます。基本的な考え方は、class_addMethod()またはmethod_setImplementationを使用して、objective-cランタイムを介してretainメソッドを「拡張」することです。これまでのところ、動作する見込みはほとんどないことを公正に警告します。まもなく、上記のperformSelector呼び出しのより頻繁なログにフォールバックする可能性があります。
幸運を!
編集これを書いたので、私はCoreFoundationの機能を発見しました。
NSLog("RetainCount: %ld", (CFGetRetainCount((__bridge CFTypeRef) anInstance));
これはすべての場合に機能するとは限りませんが、ほとんどの場合は確かです。ドキュメントを参照してください。
例外ブレークポイントを設定してみましたか?ブレークポイントパネル、左下の「+」、「例外ブレークポイントの追加...」、「完了」例外を行に分離できれば、どのオブジェクトが誤動作しているかを特定できるはずです。お役に立てれば :)