2009-08-08 10 views
0
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) 

現在、私のプログラムには非常に奇妙なエラーがあります。時にはそれが起こり、ときどき起こることもありません。しかし、ここで何が起こっているかの概要です:誰かがiPhoneアプリでこのスタックトレースについて手を差し伸べることができますか?

プログラムが起動すると:それが存在する場合

  • は(わずかplistのは13個の要素で構成されて)データを保存したがロードされます。
  • 1014文字列を含む巨大なplistがNSMutableDictionaryにロードされます。
  • 78文字列を含む別のplistがNSArrayにロードされます。
  • .mp4ムービーが再生されます。

エラーは、OpenGL ESビューが削除されている部分で発生し、ユーザーはNSMutableDictionaryの1014文字列の文字列の1つを表示しようとしています。

このエラーは、シミュレータでは発生しません。それはiPhone上でのみ発生し、ときどきうまく動作しますが、時にはそれが壊れます。

しかし、stacktraceを読んだ後、そこにCFDictionaryApplyFunctionがあるので、考えられる原因の1つかもしれないと思いました。それはシミュレータ上で、それが素早く物事を読み込むので、plistの辞書全体が即座にロードされ、デバイス上では読み込み速度が遅くなるからですか?正直なところ、私は辞書の仕組みを正確には知らない。瞬時に1014個の文字列をすべて読み込んでいますか、それとも他のスレッドを使ってゆっくり読むのですか?ご意見をお聞かせください。ありがとうございました。

+2

iPhoneではメモリが比較的小さいので、メモリ警告が発生する可能性が高くなります。シミュレータで、メモリ警告をシミュレートしてみてください( 'Hardware'メニュー項目にあるオプション)。 – notnoop

答えて

5

EXC_BAD_ACCESSを取得した場合、そのオブジェクトが存在しないオブジェクトに対してメソッドを呼び出そうとしていることがよくあります。これはおそらく、割り当てが解除されているためです。半押しトレースについて

、など呼び出し、警告いくつかのメモリがあります。あなたのコードのどれも直接クラッシュではなく、システムの原因とされていないように見えます

#12 0x30a00710 in -[UIApplication _performMemoryWarning]() 

は、メモリが不足しているときの通知。

フレーム#0に近づくと、UIImageオブジェクトのキャッシュをクリアしようとしているように見えますが、これは不正アクセスと思われます。

これに基づいて、便利なコンストラクタの自動解放された戻り値へのポインタを割り当てていると推測されます。オブジェクトはオートレリースされていますので、画像を直接使用しないので問題はないと思うかもしれませんが、メモリ警告がそのオブジェクトにアクセスしようとします。たとえば:あなたはself.myImage経由で値を設定しない限り、この例では

@interface MyClass { 
    UIImage* myImage; 
} 
// ... 
- (id) init { /* the usual stuff */ 
    myImage = [UIImage imageNamed:@"bob_the.png"]; 
    return self; 
} 

は、あなたがmyImageに設定保持特性を持っている場合でも、あなたは実際に画像を保持していません。だから、この呼び出しの直後に、イメージが解放され、あなたは人間の土地へのポインタを持っています。

コードを見ることなく、私はそれが実際に起こっているかどうかを知る方法がありませんが、それは作るのは間違いの1つのタイプです。

これらに関する質問は、同様のクラッシュについてのヒントを与える:EXC_BAD_ACCESSデバッグquestion 1question 2

最後に、それが役に立たない場合は、の最小限の複製を見つけることをお勧めします。これを行う難しい方法は、コードをコピーし、半分を切り取り、エラーがまだ存在するかどうかを確認し、エラーを再現する最小コードを見つけるまで繰り返します。通常、そこからデバッグするのはずっと簡単です(また、stackoverflowの質問として投稿することもできます)。簡単な方法がわかっている場合は、教えてください。

+0

このように割り当てることもできます: 'myImage = [[UIImage imageNamed:@" bob_the.png "] retain]'。 – notnoop

+0

あなたが言ったことによると、おそらくこの部分がトラブルの原因ですか?このコードは、UIImageViewのサブクラスのメソッドにあります。 NSString * st; st = [[NSString alloc] initWithFormat:@ "sc%d.png"、selectedNumber]; self.image = [UIImage imageNamed:st]; [st release]; 基本的には、私はUIImageViewのイメージをそのように設定しました。これが原因である可能性はありますか? – Karl

+0

エラーが発生しないことを確認するためにもう少しテストすることができます。今、私はUIImageViewサブクラスに保持されたUIImage *を持っています。ありがとう、タイラー氏。 – Karl

1

NSZombiesEnabled環境変数を設定することができます。こうすることで、リリースされたオブジェクトにアクセスするときにアプリがEXC_BAD_ACCESSでクラッシュすることはなく、有益なメッセージがコンソールに記録されます。 This blog postは、何が起こり、どのようにXCodeでそれを設定するのかをよく説明しています。とにかく、プロダクションリリースではこのオプションを無効にすることを決して忘れてはいけません。さもなければあなたのオブジェクトは決して解放されないでしょう!

関連する問題