16

そのため、アプリのリリースに備えてアプリをデバッグしており、「すべての例外」のユニバーサルブレークポイントを有効にしました。それ以来、アプリを実行するたびに、コンソールに次のように出力されます。

キャッチポイント 2 (スロー)保留中のブレークポイント 1 - 「objc_exception_throw」が解決されました

objc[11765]: クラス __NSCFLocale のオブジェクト 0x8f18ff0 がプールなしで自動解放されました - ちょうどリークしています - objc_autoreleaseNoPool() でブレークしてデバッグします

objc[11765]: クラス __NSCFNumber のオブジェクト 0x8f190a0 は、プールが配置されていない状態で自動解放されました - ちょうどリークしています - objc_autoreleaseNoPool() でブレークしてデバッグします

objc[11765]: クラス __NSCFLocale のオブジェクト 0x8f1fef0 がプールなしで自動解放されました - ちょうどリークしています - objc_autoreleaseNoPool() でブレークしてデバッグします

文字通り3回印刷されました。これが何を意味するのかわかりませんが、見た目が悪いです。アドバイスをいただければ幸いです。

4

3 に答える 3

35

新しい情報

スウィズル自動解放メソッドを作成することで、問題がどこにあるかを特定しました。

自分が何をしているのかわからない限り、それを行うことはお勧めしませんが、これが私が見つけたものです。

+ (void) load; //Method is called outside the original autorelease pool.
+ (void) initialize; // Method is called outside the original autorelease pool.

NSThread は独自のスレッドを作成し、呼び出されたメソッドは自動解放プールにラップする必要があります。

Grand Central Dispatch は、「dispatch_...」コマンドを使用する際に、自動解放プールを調整します。ただし、手動で発送する場合。自動解放プールにラップすることもできます。

また、ARC は、自動解放がプール外で発生することを通知する処理を行いません。

したがって、ARC を使用していて、自動解放プールの外にいることがわかっている場合。そして、それについてあなたができることは何もありません。すべての便利なメソッドを避けたいと思うでしょう。

これを使って。

[[NSString alloc] initWithFormat:@"%@",myObject];

これの代わりに

[NSString stringWithFormat:@"%@",myObject];

これにより、arc システムは保持および解放できますが、便利なメソッドを使用していないため、便利なメソッドによって行われる基本的な自動解放はスキップされます。

それが役立つことを願っています。

元の回答

わかりました、この質問に十分な詳細が回答されているとは思いません。

提示されたメッセージは

objc[1310]: Object 0x34f720 of class SimpleKeychain autoreleased with no pool in place - just leaking - break on objc_autoreleaseNoPool() to debug

デバッガーは、状況のデバッグに役立つ可能性のあるブレークポイントを指摘しています。このブレークポイントは、状況のデバッグにはほとんど役に立ちませんでした。そのブレークポイントをデバッガーに追加する方法を知ることが重要だと思うので、そのエラーでブレークするまで、(インターネットを精査して何も見つからなかった後) いじくり回すことに時間を費やしました。

すべてのエラーで中断してもこれがキャッチされないのはちょっと面倒ですが、デバッガーにブレークポイントを追加する手順は次のとおりです。

最初に行うことは、デバッガーのブレークポイント ナビゲーターを選択することです

ナビゲーター ツールバー

このタブをクリックすると

ブレークポイント ボタン

次に、ナビゲーター ペインの下部を見て、プラス ボタンを押します。

例外ブレークポイントを追加

これにより、ブレークポイントを手動で追加できます。

C++ ブレークポイントを選択し、名前テキスト フィールドにメッセージ名を入力しました。

カスタム C++ 例外の追加

この例外を追加した後、実際には壊れました。

ただし、これは目的の C 開発者として役立つ場合とそうでない場合があります。これは、アセンブリ コードに侵入しました。

達成されたブレークポイントでのアセンブリ コード。

残念ながら、スレッドのコール スタックにこのポイントしか表示されませんでした。

スレッド一覧

そして、autorelease の問題は、クラスが dispatch_once 呼び出しで autorelease を呼び出したためであることが判明しました。さらなる調査により、+(void)負荷が明らかになりました。クラスのメソッドが何よりも先に呼び出されました。これは call_load_methods 関数を介して行われ、メイン メソッドのスレッドの外側にあります。

エラーコールとスタック

これを修正するために、呼び出しの周りに autorelease プール ラッパーを追加しただけです。

更新されたエラー コール

別の解決策として、+(void)load 内に autorelease プールを追加することもできます。方法。しかし、これは私の用途には十分でした。

注:問題を見つけて、結果の回答へのすべてのパスを把握できないのが好きではないため、これを投稿に追加しています。リストされた関数にブレークポイントを追加するようにデバッガーが指示した場合、その情報を取得するための情報がどこかにあるはずです。うまくいけば、これがこの答えを見つけようとしている人々の不満を軽減するでしょう.

于 2012-06-05T20:31:18.247 に答える
1

これは、発生するスレッドに自動解放プールを作成する必要があることを意味します。そうしないと、割り当てられたオブジェクトは破棄されません(メッセージで示されているように)。したがって、シンボルでブレーク/一時停止してから、スタックをスレッド(またはプログラム)エントリまで移動し、自動解放プールを追加します。それで全部です。

于 2012-04-04T02:20:45.420 に答える