誰かがiPhoneアプリのこのスタックトレースについて教えてくれませんか?
-
12-09-2019 - |
質問
Program received signal: “EXC_BAD_ACCESS”.
(gdb) bt
#0 0x30011940 in objc_msgSend ()
#1 0x30235f24 in CFRelease ()
#2 0x308f497c in -[UIImage dealloc] ()
#3 0x30236b78 in -[NSObject release] ()
#4 0x30a002a0 in FlushNamedImage ()
#5 0x30250a26 in CFDictionaryApplyFunction ()
#6 0x30a001a4 in _UISharedImageFlushAll ()
#7 0x30a00738 in +[UIImage(UIImageInternal) _flushCacheOnMemoryWarning:] ()
#8 0x3054dc80 in _nsnote_callback ()
#9 0x3024ea58 in _CFXNotificationPostNotification ()
#10 0x3054b85a in -[NSNotificationCenter postNotificationName:object:userInfo:] ()
#11 0x3054dbc0 in -[NSNotificationCenter postNotificationName:object:] ()
#12 0x30a00710 in -[UIApplication _performMemoryWarning] ()
#13 0x30a006a8 in -[UIApplication _receivedMemoryNotification] ()
#14 0x30a005d8 in _memoryStatusChanged ()
#15 0x30217416 in __CFNotificationCenterDarwinCallBack ()
#16 0x3020d0b0 in __CFMachPortPerform ()
#17 0x30254a76 in CFRunLoopRunSpecific ()
#18 0x3025416a in CFRunLoopRunInMode ()
#19 0x320452a4 in GSEventRunModal ()
#20 0x308f037c in -[UIApplication _run] ()
#21 0x308eea94 in UIApplicationMain ()
#22 0x00002096 in main (argc=1, argv=0x2ffff514)
現在、プログラムに非常に奇妙なエラーがあります。それが起こることもあれば、起こらないこともあります。しかし、何が起こっているかを要約すると次のとおりです。
プログラムが起動すると:
- 保存されたデータ (13 要素で構成される短い plist) が存在する場合はロードされます。
- 1014 個の文字列を含む巨大な plist が NSMutableDictionary にロードされます。
- 78 個の文字列を含む別の plist が NSArray にロードされます。
- .mp4 ムービーが再生されます。
このエラーは、OpenGL ES View が削除され、ユーザーが NSMutableDictionary の 1014 個の文字列のうちの 1 つの文字列を表示しようとしている部分で発生します。
このエラーはシミュレーターでは発生しません。iPhone でのみ発生し、正常に動作することもありますが、クラッシュすることもあります。
しかし、スタックトレースを読んだところ、そこに CFDictionaryApplyFunction があったので、それが考えられる原因の 1 つである可能性があると考えました。シミュレーターでは読み取りが非常に速いため、plist の辞書全体が瞬時に読み込まれますが、デバイスでは読み取りが遅いためですか?正直に言うと、辞書がどのように機能するのか正確にはわかりません。1014 文字列すべてを瞬時に読み込むのでしょうか、それとも他のスレッドを使用してゆっくり読み込むのでしょうか?ご意見をお聞かせください。ありがとう。
解決
EXC_BAD_ACCESS
を取得すると、、それは多くの場合、あなたが存在しないオブジェクトのメソッドを呼び出すようにしようとしていること - 。それが割り当て解除されていますおそらくので、
半押し跡について、のようないくつかのメモリの警告の呼び出しがあり、
#12 0x30a00710 in -[UIApplication _performMemoryWarning] ()
あなたのコードのいずれでもないように見えますどのの直接のメモリが不足したときにクラッシュするのではなく、システム通知を引き起こします。
#0をフレームにクローサー、それはUIImage
オブジェクトのキャッシュをクリアしようとしているように見えるが、これは悪いのアクセスのように見えます。
これに基づき、1つの推測では、コンビニエンスコンストラクタの自動解放戻り値へのポインタを代入しているということです。その後、オブジェクトが自動解放され、そしてあなたが直接画像を使用していないので、それは罰金だと思うかもしれないが、メモリ警告がそれにアクセスしようとします。たとえばます:
@interface MyClass {
UIImage* myImage;
}
// ...
- (id) init { /* the usual stuff */
myImage = [UIImage imageNamed:@"bob_the.png"];
return self;
}
あなたはmyImage
経由で値を設定しない限り、この例では、あなたがself.myImage
に設定保持特性を持っている場合でも、あなたは実際に画像を保持していません。だから、すぐにこの呼び出しの後、画像が解放され、そしてあなたがいない人の土地へのポインタを持っています。
は、コードを見てなければ、私はそれが実際に何が起こっているかどうかを知る方法はありませんが、それは作るのは簡単だ間違いの1種類です。
これらの関連の質問は、同様のクラッシュについてのヒントを与える:のEXC_BAD_ACCESS
のデバッグの質問1 と質問2 のます。
最後に、私はあなたの問題のの最小限の再生をを見つけることをお勧めします。あなたが見つけることができる最小のコードがエラーを再現し得るまでこれを行うには、ハードな方法は、あなたのコードをコピーして半分を切り取って、エラーがまだあるかどうかを確認し、繰り返すことです。それは(あまりにも、stackoverflowの質問として、より投稿可能!)、そこからデバッグする通常はるかに簡単です、あなたが簡単な方法を知っていれば、私に知らせます。
他のヒント
あなたはNSZombiesEnabled
環境変数を設定することもできます。この方法は、あなたのアプリがリリースされたオブジェクトにアクセスするときEXC_BAD_ACCESS
でクラッシュではなく、あなたのコンソールに情報メッセージをログに記録しません。何が起こるかをかなりよく説明する このブログの記事とどのようにXcodeでそれを設定します。そうでない場合は、あなたのオブジェクトが解放されることはありませんので、とにかく、EVER、生産のリリースでは、このオプションを無効にすることを忘れないでください!