2012-03-21 4 views
3

必要があるときにオブジェクトを削除ARCをデバッグする方法(ARCでコンパイルされました) 。デバッグビルドでは、すべてが問題ありません。それは明確にすべきではないときにオブジェクト(IVAR、NSMutableDictionary)がリリースビルドで削除されている場所、それは私が私のiOSゲーム内のケースを持っていない

私はこれをデバッグする最良の方法を見つけようとしています。私がオブジェクトに対して何らかのチェックをしたら、それは必要なときにハングアップします。私は、オブジェクトがアクセスされているので、アプリケーションがクラッシュするため、オブジェクトが使用されていることを知っています。

私は、オブジェクトが削除されていることを伝えるためにゾンビオブジェクトを使用しますが、いつどこでそれが起こっている私は知りません。

ですが、コンパイラは、これはもはや必要ありませんオブジェクトまたは実際に削除されているとき(それが自動解放プールにいた場合、私には何も教えてくれないかもしれない)と思ったときに私が見るための方法。

これを追跡するのによいアドバイスはありますか?私はこれをコンパイラのバグと呼ぶのは嫌ですが、コンパイラがどのようにこのオブジェクトが参照されていないと思うか分かりません。 ivarを保持するオブジェクトは、すべてのコードが実行されている場所なので、明らかにまだ周囲にあります(そうでない場合は、さらに悪いことが起きます)。

は、今の私はちょうどそれにコードのデバッグの1行が削除されないようにオブジェクトを引き起こすことを去るつもりですが、私はそのソリューションとアプリケーションを出荷すること嫌い。

ありがとうございました。

+0

この問題に関する追加情報はありますか?私はちょうどそれが保持する必要があるオブジェクトを削除するARCを扱う-O0以外の最適化でコンパイルするとクラッシュしました... – fbrereto

+0

xcodeが更新されたときにバグが私のためにやってきました。それは9ヶ月前であり、以来、問題を抱えていました。 –

+0

よろしくお願いいたします。 CGPointを単なるObjective-Cクラスのメンバーではなくプロパティにしてしまったとき、それは去ってしまったという奇妙な問題でした。奇妙だが、少なくとも問題は解決されている。 – fbrereto

答えて

1

デバッグコードを配置する場所は、オブジェクトのdeallocメソッドです。ここにブレークポイントを置くことができます(リリースモードでも)。

最も可能性の高い原因は、一部のコードがリリースで並べ替えまたは削除されていることです。

あなたが言うとき、「それはすべての場所で参照されています、」あなたは、そのプロパティにそれへの強い参照を保持しているオブジェクトを持っていることを意味するのですか?メモリ管理の最初のルールは、あなたが気にしているものを保持し(ivarに入れて)、あなたが気にしないものを解放することです。あなたがこのオブジェクトを気にするオブジェクトを持っているなら、それらを指す強い特性を持つべきです。彼らがそうするなら、それは確かに離れてはいけません。


ARCでの強いポインタのダングリングは、コードに深刻な問題を示唆しています。私はあなたがブリッジキャスト(特に__bridge)を使用している場所を探して始めます。ポインタを無効にするオブジェクトを間違って渡していないことを確認してください。

C配列の使用方法を見てください。 C配列の終わりを辿ると、他のメモリが破壊され、このような問題が発生する可能性があります。

同様に、とNSDataのように、length引数を使用するものの使用を監視します。長すぎる値を渡すと、データの最後から離れて他の変数が破損する可能性があります。同様に、mallocメモリ経由で生ポインタを持つもの。

+0

問題のオブジェクトはNSMutableDictionaryであり、1つのivarに保持されていますが、私のコード全体で参照されているので、コンパイラがもう使用されていないと思うとは思えません。それをサブクラス化して、deallocにブレークポイントを置くことができます。コンパイラがそれがもう使用されていないと思って削除していると思うなら、ARCはコンパイラの魔法のほんの一部であるので、私はそれについて何をしているのか分かりません。かなりストレートなようなものの周りにこぼれ落とさなければならないのは奇妙だと感じています。 –

+0

さて、それは簡単だと言われています。 NSMutableDictionaryをフープジャンプすることなくサブクラス化することはできません。 NSMutableDictionaryのdeallocを簡単に破る方法はありますか? –

+0

申し訳ありません。私はオブジェクトが辞書であることを忘れました。それを根本的に変更するサブクラス化(これはフリートライブリッジクラスではありません)。しかし、コードが辞書を「参照する」という事実は、それが強い参照を持っているかどうかとは何の関係もありません。それが強いivarの場合、それは生きる必要があります。そうでなければ、いつでも去ることができます。もしそれが象牙の中に消え去っているなら、あなたはおそらくそれがその象牙の中にあるのは間違っているでしょう。あなたがそれが実際に象牙の中にない理由を調べるべきです。 –

1

今日、問題に遭遇しました。この問題は、あなたがここにたどり着いたように聞こえます。私たちは、plistファイルからロードされたNSDictionaryのカスタムメソッドを使用してクラスをロードしています。私たちのアプリケーションは、そのメソッドの最後に、二重のリリースのためにクラッシュします。私たちは、リリースバイナリの最適化を無効にすることは、それを修正するためにすべて行うことができることを発見しました。

現在、クラッシュの原因となっているメソッド(これは約2か月間正常に実行されています)に関連するコードは変更されていません。問題がどこで発生したのかを数時間確認した結果、現時点で修正できるのは、リリースコードで「最適化レベル」を「なし」に変更することだけです。 >ターゲット - - >バイナリ名 - >設定をビルド - >最適化レベル - >

を解放し、それを設定する 'なし-O0' ..

プロジェクトに移動します。

私は、オプティマイザで発生している非常に奇妙なバグがあると推測することができますが、これがあなたに役立つことを願っています!

+0

多くの調査の後、私は自分の問題がコンパイラの問題であると確信しています。私はちょうどxcode 4.3をインストールしたので、私は戻ってこれが続くかどうかを確認する必要があります。それは私はそれのためのアップルのバグを提出する必要があります。 –

1

これは私にも起こっていますが、弱いIBOutletsで起こっています。

@property (nonatomic, weak) IBOutlet UIView *blahView; 

… 

[self.blahView removeFromSuperview]; 
[self.otherView addSubview:self.blahView]; 

最初の行のコンパイラは、オブジェクトへの参照がなくなり、それを解放/削除すると考えます。

弱い参照ivarを保持し、これを実行するために一時変数(範囲内)を使用すると、コンパイラはそれを解放しないようにします。

UIView *blahView = self.blahView; 
[blahView removeFromSuperview]; 
[self.otherView addSubview:blahView]; 

これで問題が解決しますか?

関連する問題