296

アプリケーションをデバイスにデプロイすると、数サイクル後にプログラムが終了し、次のエラーが表示されます。

Program received signal: "EXC_BAD_ACCESS".

このプログラムは、iPhone シミュレーターで問題なく実行されます。一度に 1 つずつ手順を実行する限り、プログラムはデバッグおよび実行されます。もう一度走らせたらすぐにEXC_BAD_ACCESS信号を打ちます。

この特定のケースでは、たまたま加速度計コードのエラーでした。シミュレーター内では実行されないため、エラーは発生しませんでした。ただし、デバイスに展開されると実行されます。

この質問への回答のほとんどは一般的なエラーを扱っているEXC_BAD_ACCESSため、恐ろしい不正アクセス エラーのキャッチオールとしてこれを開いたままにします。

EXC_BAD_ACCESS通常、不正なメモリ アクセスの結果としてスローされます。詳細については、以下の回答を参照してください。

以前に信号に遭遇したことがEXC_BAD_ACCESSありますか?どのように対処しましたか?

4

36 に答える 36

201

あなたの説明から、最も可能性の高い説明は、メモリ管理にエラーがあることだと思います。あなたはiPhoneの開発に数週間取り組んでいると言いましたが、ObjectiveC全般の経験があるかどうかはわかりません。別のバックグラウンドを持っている場合は、メモリ管理ルールを実際に内部化するまでに少し時間がかかることがあります。

割り当て関数(通常は静的allocメソッドですが、他にもいくつかあります)またはコピーメソッドから取得するものはすべて、メモリも所有しているため、完了したら解放する必要があることを忘れないでください。

しかし、ファクトリメソッド(例)を含む他のほとんどのものから何かを取り戻す場合[NSString stringWithFormat]は、自動リリース参照があります。これは、将来、他のコードによってリリースされる可能性があることを意味します。したがって、必要に応じてそれが重要です。あなたがそれを保持する直接の機能を超えてそれを維持するため。そうしないと、メモリは使用中に割り当てられたままになるか、解放されても、エミュレータのテスト中に偶然に有効である可能性がありますが、デバイスで実行すると解放されて不正アクセスエラーとして表示される可能性が高くなります。

これらを追跡するための最良の方法、そしてとにかく(明らかな問題がない場合でも)良いアイデアは、特にリークオプションを使用して、機器ツールでアプリを実行することです。

于 2008-11-29T23:17:07.427 に答える
101

EXC_BAD_ACCESSの主な原因は、解放されたオブジェクトにアクセスしようとすることです。

これをトラブルシューティングする方法については、次のドキュメントをお読みください: DebuggingAutoReleasePool

「自動解放されたオブジェクトをリリースしている」とは思わない場合でも、これは適用されます。

この方法は非常にうまく機能します。いつも使って大成功!!

要約すると、これは、CocoaのNSZombieデバッグクラスとコマンドライン「malloc_history」ツールを使用して、コードでアクセスされたリリース済みオブジェクトを正確に見つける方法を説明しています。

サイドノート:

機器を実行してリークをチェックしても、EXC_BAD_ACCESSのトラブルシューティングには役立ちません。メモリリークはEXC_BAD_ACCESSとは何の関係もないと確信しています。リークの定義は、アクセスできなくなったオブジェクトであるため、呼び出すことはできません。

更新: 現在、Instrumentsを使用してリークをデバッグしています。Xcode 4.2から、[製品]-> [プロファイル]を選択し、Instrumentsが起動したら、[ゾンビ]を選択します。

于 2009-07-01T07:27:49.463 に答える
12

EXC_BAD_ACCESS シグナルは、無効なポインタをシステム コールに渡した結果です。私は、OS X のテスト プログラムを使って、今日 1 つ取得しました。初期化されていない変数を に渡していましたpthread_join()。これは、以前のタイプミスが原因でした。

私は iPhone の開発に詳しくありませんが、システム コールに渡すすべてのバッファ ポインタを再確認する必要があります。コンパイラの警告レベルを完全に上げます (gcc では、オプション-Wall-Wextraオプションを使用します)。シミュレーター/デバッガーでできるだけ多くの診断を有効にします。

于 2008-11-29T04:08:40.223 に答える
8

私の経験では、これは通常、不正なメモリ アクセスが原因です。すべてのポインター、特にオブジェクト ポインターをチェックして、それらが初期化されていることを確認します。MainWindow.xib ファイルを使用している場合は、適切にセットアップされ、必要なすべての接続が行われていることを確認してください。

紙上のチェックで何も起こらず、シングルステップでエラーが発生しない場合は、NSLog() ステートメントでエラーを見つけてみてください。コードにそれらを振りかけ、原因となっている行を特定するまでそれらを移動します。エラー。次に、その行にブレークポイントを設定して、プログラムを実行します。ブレークポイントに到達したら、すべての変数とその中のオブジェクトを調べて、期待どおりに見えないものがあるかどうかを確認します。特に、オブジェクト クラスが予期しないものである変数に注意してください。変数に UIWindow が含まれているはずなのに、代わりに NSNotification が含まれている場合、デバッガーが動作していないときに、同じ根本的なコード エラーが別の方法で現れる可能性があります。

于 2008-11-29T22:49:35.920 に答える
7

EXC_BAD_ACCESS の追跡に数時間費やしたところ、NSZombies やその他の環境変数が何も教えてくれないようでした。

私にとっては、フォーマット指定子を含む愚かな NSLog ステートメントでしたが、引数は渡されませんでした。

NSLog(@"Some silly log message %@-%@");

によって修正されました

NSLog(@"Some silly log message %@-%@", someObj1, someObj2);
于 2009-10-26T03:59:07.273 に答える
7

2010 WWDC ビデオは、Apple 開発者プログラムの参加者なら誰でも利用できます。「Session 311 - Advanced Memory Analysis with Instruments」という素晴らしいビデオがあり、インストゥルメントでゾンビを使用し、その他のメモリの問題をデバッグする例を示しています。

ログインページへのリンクについては、ここをクリックしてください

于 2010-10-19T20:31:36.907 に答える
6

objc_exception_throw にブレークポイントを設定すると便利です。そうすれば、EXC_BAD_ACCESS を取得したときにデバッガーが壊れるはずです。

手順はここにあります。DebuggingTechniques

于 2009-12-07T00:44:44.943 に答える
6

完全な答えではありませんが、これを受け取った特定の状況の 1 つは、autorelease を使用しようとしたために「死んだ」オブジェクトにアクセスしようとしたときです。

netObjectDefinedInMyHeader = [[[MyNetObject alloc] init] autorelease];

したがって、たとえば、実際にはこれをオブジェクトとして「通知」に渡していましたが(リスナー、オブザーバー、好きなイディオムとして登録しました)、通知が送信されるとすでに終了しており、EXC_BAD_ACCESSを取得します。必要に応じて変更し[[MyNetObject alloc] init]て後で解放すると、エラーが解決しました。

これが発生する別の理由は、たとえば、オブジェクトを渡して保存しようとした場合です。

myObjectDefinedInHeader = aParameterObjectPassedIn;

後で myObjectDefinedInHeader にアクセスしようとすると、問題が発生する可能性があります。使用:

myObjectDefinedInHeader = [aParameterObjectPassedIn retain];

必要なものかもしれません。もちろん、これらは私が遭遇したもののほんの一例であり、他の理由もありますが、これらはとらえどころのないものであることが判明する可能性があるため、それらについて言及します. 幸運を!

于 2008-12-01T05:20:51.090 に答える
5

これが発生する可能性がある別の状況を追加するだけです:

私はコードを持っていました:

NSMutableString *string;
[string   appendWithFormat:@"foo"];

明らかに、文字列にメモリを割り当てるのを忘れていました。

NSMutableString *string = [[NSMutableString alloc] init];
[string   appendWithFormat:@"foo"];

問題を修正します。

于 2009-07-23T11:07:06.840 に答える
5

EXC_BAD_ACCESS 例外を発生前にキャッチするもう 1 つの方法は、XCode 4+の静的アナライザーです。

Product > Analyze (shift+cmd+B) で静的アナライザーを実行します。アナライザーによって生成されたメッセージをクリックすると、問題のあるオブジェクトの保持/解放のシーケンスを示す図がソースにオーバーレイされます。

ここに画像の説明を入力

于 2012-12-26T19:15:18.873 に答える
4

「割り当てまたは保持していない場合は、解放しない」という単純なルールを使用してください。

于 2010-02-17T08:15:14.983 に答える
4

EXC_BAD_ACCESS をデバッグする方法

上記のリンクをチェックして、そのとおりに実行してください.... NSZombies を使用するための簡単な手順

アプリケーションを実行し、失敗した後 (「EXC_BAD_ACCESS」ではなく「中断」と表示されます... コンソールを確認します ([実行] > [コンソール])... アクセスしようとしたオブジェクトを示すメッセージがそこにあるはずです。

于 2010-09-15T19:13:09.833 に答える
3

これは素晴らしいスレッドです。これが私の経験です: プロパティ宣言の保持/割り当てキーワードを台無しにしました。私は言った:

@property (nonatomic, assign) IBOutlet UISegmentedControl *choicesControl;
@property (nonatomic, assign) IBOutlet UISwitch *africaSwitch;
@property (nonatomic, assign) IBOutlet UISwitch *asiaSwitch;

どこで言うべきだった

@property (nonatomic, retain) IBOutlet UISegmentedControl *choicesControl;
@property (nonatomic, retain) IBOutlet UISwitch *africaSwitch;
@property (nonatomic, retain) IBOutlet UISwitch *asiaSwitch;
于 2010-05-03T00:50:31.770 に答える
3

EXC_BAD_ACCESS の扱い方

EXC_BAD_ACCESS エラーがスローされると、xcode が main.m クラスにエラーを表示し、クラッシュが発生した場所に関する追加情報を提供しないと感じることがあります (時々)。

そのような場合、Xcode で例外ブレークポイントを設定して、例外がキャッチされたときにブレークポイントが配置され、その行でクラッシュが発生したことをユーザーに直接知らせることができます。

ここに画像の説明を入力

于 2014-01-07T09:17:17.660 に答える
3

大きな配列を含む C メソッドを実行しようとしているときにのみ、iPhone で EXC_BAD_ACCESS に遭遇しました。シミュレーターはコードを実行するのに十分なメモリを提供できましたが、デバイスは提供できませんでした (配列は 100 万文字だったので、少し過剰でした!)。

EXC_BAD_ACCESS は、メソッドのエントリ ポイントの直後に発生し、配列宣言の近くになかったため、かなり長い間混​​乱していました。

おそらく、私の数時間の髪を引っ張ることで、他の誰かが恩恵を受けるかもしれません.

于 2010-06-28T12:49:07.887 に答える
3

から割り当てられていないポインタを取り出すのを忘れましたdealloc。UINavigationController の rootView で exc_bad_access を取得していましたが、たまにしかありませんでした。viewDidAppear{} の途中でクラッシュしていたため、問題は rootView にあると思いました。これは、不適切な dealloc{} リリースでビューをポップした後にのみ発生することが判明しました。それだけです!

"EXC_BAD_ACCESS" [プロセス 330 に切り替えています] 現在、プログラムに使用できるメモリがありません: malloc を呼び出すのは安全ではありません

割り当てようとしているところに問題があると思いました...非割り当てを解放しようとしていたところではありません、D'oh!

于 2010-03-04T05:40:56.960 に答える
3

init-Method で self を返すのを忘れていました... ;)

于 2010-02-09T11:54:40.950 に答える
3

完了したら「文字列」を解放していることを願っています!

于 2009-08-24T02:04:38.053 に答える
2

エラーの内容を確認するには

NSZombieEnabled を使用します。

アプリケーションで NSZombieEnabled 機能を有効にするには:

[Project] > [Edit Active Executable] を選択して、実行可能ファイルの情報ウィンドウを開きます。[引数] をクリックします。「環境に設定する変数」欄の追加(+)ボタンをクリックします。[名前] 列に NSZombieEnabled と入力し、[値] 列に YES と入力します。NSZombieEnabled エントリのチェックマークが選択されていることを確認します。

iPhoneSDKでこの回答を見つけました

于 2011-02-23T16:52:22.710 に答える
2

無限再帰がある場合、このエラーも発生する可能性があると思います。これは私の場合でした。

于 2014-04-13T19:36:05.037 に答える
2

メソッド パラメーターを検証するための NSAssert() 呼び出しは、追跡して nil の受け渡しを回避するのにも非常に便利です。

于 2008-11-30T14:39:46.317 に答える
2

追加するだけ

Lynda.comには素晴らしい DVD があります。

iPhone SDK エッセンシャル トレーニング

第 6 章のレッスン 3 では、EXEC_BAD_ACCESSとゾンビの操作について説明します。

エラー コードだけでなく、Zombies を使用してリリースされたオブジェクトに関する詳細情報を取得する方法を理解できてよかったです。

于 2010-04-05T11:16:18.037 に答える
2

過去 4 時間、このエラーを解決するためにコードのデバッグとリファクタリングを行ってきました。上記の投稿により、問題が発生しました。

前のプロパティ:

startPoint = [[DataPoint alloc] init] ;
startPoint= [DataPointList objectAtIndex: 0];
x = startPoint.x - 10; // EXC_BAD_ACCESS

後のプロパティ:

startPoint = [[DataPoint alloc] init] ;
startPoint = [[DataPointList objectAtIndex: 0] retain];

さようならEXC_BAD_ACCESS

ご回答ありがとうございます。私は一日中この問題に苦しんでいます。あなたは素晴らしいです!

于 2009-05-30T23:48:57.387 に答える
2

これはしばらく前に尋ねられたことに気づきましたが、このスレッドを読んだ後、XCode 4.2 の解決策を見つけました: Product -> Edit Scheme -> Diagnostics Tab -> Enable Zombie Objects

割り当て解除されたオブジェクトに送信されているメッセージを見つけるのに役立ちました。

于 2012-02-14T04:46:51.710 に答える
2

私はちょうどこの問題を抱えていました。私にとっての理由は、CoreData管理オブジェクトを削除し、後で別の場所から読み取ろうとしたことです。

于 2009-12-10T14:38:15.100 に答える
1

さらに別の可能性:キュー内のブロックを使用すると、この時点ですでに割り当てが解除されている別のキュー内のオブジェクトにアクセスしようとする可能性があります。通常、GUIに何かを送信しようとするとき。例外ブレークポイントが奇妙な場所に設定されている場合は、これが原因である可能性があります。

于 2012-11-29T09:07:48.633 に答える
1

[self performSegueWithIdentifier:sender:]私は使用していなかったので、私はそれを手に入れまし-(void) prepareForSegue:(UIstoryboardSegue *)

于 2013-01-21T23:52:10.827 に答える
1

XCode 4 以降では、Instruments で非常にシンプルになりました。Instruments で Zombies を実行するだけです。このチュートリアルでは、よく説明しています: exc_bad_access エラーのデバッグ xcode インストゥルメント

于 2012-03-09T12:02:22.170 に答える
1

@文字列を作成するときに記号をC-strings忘れないでNSStringsくださいEXC_BAD_ACCESS

これを使って:

@"Some String"

これではなく:

"Some String"

PS - 通常、array多くのレコードを含む のコンテンツを入力する場合。

于 2012-10-18T21:09:27.630 に答える
-1

私の場合、テーブルビューの削除操作が原因でした。このソリューションは、私の悪いアクセス例外を解決しました: https://stackoverflow.com/a/4186786/538408

于 2015-01-12T10:57:48.043 に答える