2011-12-08 5 views
0

と意見を変えたときに、私はこのコードのチャンクを使用して私のアプリでビューを切り替えるしようとしている:EXC_BAD_ACCESSエラーPresentModalViewController

self->variable1 = [[NSNumber alloc] initWithInt:0]; 
self->variable2 = [[NSMutableArray arrayWithCapacity:1]; 
self->variable3 = [[NSMutableArray arrayWithCapacity:1]; 

[self presentModalViewController:titleScreen animated:YES]; 

私が割り当てられた変数ラインのすべてをコメントアウトした場合、コードは正常に動作します。コード内の1行だけを残すと、 "EXC_BAD_ACCESS"エラーが発生してクラッシュします。なぜこうなった?変数はまったく使用されておらず、後で使用するために宣言されています。私はどちらの行にもコンパイルエラーを表示しません。私は間違って何をしていますか?

更新日:
ご協力いただきありがとうございます。私は自分の変数を@ property/@ synthに宣言してコードを整理する方法を変更しますが、問題を修正しませんでした。私はそれを修正しました。これに

self.variable1 = [[NSNumber alloc] initWithInt:0]; 

:私はこれからのコードを変更し

self.variable1 = [NSNumber alloc]; 
[self.variable1 initWithInt:0]; 

、それが働きました!誰かがなぜこれが働いて、最初の行がしなかったのか説明できますか?

更新:

私に私の邪悪な方法を示すためにあなたのピーターHoseyありがとうございます。今回は固定されていると確信しています。私は自分の変数を格納していました。

-(void)release 

xCodeは必要なときにリリースされるとは思いませんでした。私はすべての変数リリースを

に移動しました
-(void)Destroy 

私はMYコマンドですべてをリリースすることができます。今すぐコードが動作します。再度、感謝します!

+0

- Objective-Cのプロパティを参照する>オペレータは奇妙に思えます。 –

+0

変数はクラス内のプロパティとして宣言されていますか?アクセサメソッドを合成するか、少なくともそれらを正しく実装しましたか? 'self'を使うとsetterメソッドが呼び出されるので、問題が内部にある可能性があります。 –

+1

'self.variable1 = ;(' '@のproperty'と' @のsynthesize'を想定)**セッターを呼び出すことになります。 'self-> variable1 = ;を使うと、**はできません**。完全に合法的な構文( '@ public' ivarsを前提とする)ですが、Objective-Cの良い習慣ではありません。 – gschandler

答えて

1

variable1,variable2、およびvariable3をプロパティとして使用し、インスタンス変数は使用しません。次に、self.variable1,self.variable2、およびself.variable3を使用してアクセスします。

ドット構文(self.variable1など)は、各プロパティで宣言したメモリ管理ポリシーを使用します。矢印の構文(self->variable1など)は変数に直接アクセスします。クラッシュは、離れた場所に2つの配列を作成しておき、所有していない配列を保持するプロパティに配列を割り当てなかったためです。

ARCを使用するようにプロジェクトをアップグレードすることもできます。次に、メモリ管理の違いはありません。プロパティではなくインスタンス変数に割り当てることで、オブジェクトが早すぎて解放されることはありません。なぜなら、ARCはインスタンス変数がデフォルトで所有権であるとみなすからです。 ARCに切り替えた後でもプロパティを使用するように切り替えることはできますが、クラッシュを防ぐことはできません。あなたの編集に対応して


私は私のコードをクリーンアップするために、@プロパティ/ @シンセに私の変数を宣言する方法を変更するが、それは問題を解決しませんでした。

次に何かが間違っていました。

あなたは問題自体についてはあまり言わなかった。 EXC_BAD_ACCESSがあると言っていますが、どのような声明がクラッシュを引き起こしたのか、また、あなたが示したコードにあなたが責任を負う根拠はありません。

私はこのコードから変更:

self.variable1 = [[NSNumber alloc] initWithInt:0]; 

しかし、正しいコードです。それがあなたが使用すべきものです。これに

self.variable1 = [NSNumber alloc]; 
[self.variable1 initWithInt:0]; 

Noooo!そのコードは複数のレベルで間違っている、間違っている、間違っています。

initメソッド(メソッドを含む)は、メッセージの送信先と同じオブジェクトを返すとは限りません。 NSNumberのinitWithInt:はおそらくではないです。

このオブジェクトは、未初期化 NSNumberオブジェクトを作成し、それをプロパティに割り当てます。その後、そのオブジェクトにinitWithInt:を送信します。初期化されたオブジェクトが返されます。があり、はおそらく別のオブジェクトになります。これで初期化されていないオブジェクト(後で使用しようとする)が保持され、初期化されたオブジェクトが床にドロップされました。

allocinitWith…)を別々の式で送信しないでください。常に同じ表現でそれらを送信してください。例外なく。それ以外の場合は、初期化されたオブジェクトではなく、初期化されていないオブジェクトが保持されます。あなたのケースでは(NSNumbersで)、それはほぼ確実に起こります。

あなたがしなければならないことは、NSNumberオブジェクトを所有する強力なプロパティを宣言して合成し、単一のステートメントでNSNumberオブジェクトを作成することです:[[NSNumber alloc] initWithInt:]または[NSNumber numberWithInt:]です。 ARCを使用していない場合、プロパティはオブジェクトを保持するため、ARCを使用します。 ARCを使用している場合、効果的に同等です。

このコードでクラッシュした場合は、が間違っていますこの質問や新しい質問で私たちに教えてください。それ。デフォルトでは

1

variable2およびvariable3は、実際にモーダルビューを表示した後に(おそらく)それらに実際にアクセスする前にオートレリースされています。

非常に少なくともへのライン変更:

self->variable2 = [[NSMutableArray arrayWithCapacity:1] retain]; 
self->variable3 = [[NSMutableArray arrayWithCapacity:1] retain]; 

または

self->variable2 = [[NSMutableArray alloc] initWithCapacity:1]; 
self->variable3 = [[NSMutableArray alloc] initWithCapacity:1]; 

variable1は問題ないはずです。

ベストはそうあなたがドット表記を使用することができます@property@synthesizeを使用することです:

私はあなたが宣言することを示唆しているの.h

@interface MyClass : SuperClass 

@property (nonatomic,retain) NSMutableArray *variable2; 
@property (nonatomic,retain) NSMutableArray *variable3; 

@end 

.M

@implementation MyClass 
@synthesize variable2,varible3; 

- (void)foo { 

    self.variable2 = [NSMutableArray arrayWithCapacity:1]; 
    self.variable3 = [NSMutableArray arrayWithCapacity:1]; 

} 

@end 
0

、Objective-Cの中のすべてのインスタンス変数はスコープを保護しています。あなたが明示的に自分のインターフェイスファイルでそれらをパブリック宣言していない限り:

@interface MYClass { 

@public 
    NSNumber *variable1; 
    NSMutableArray *variable2; 
    NSMutableArray *variable3; 
} 
//... 
@end 

それらは構造体の間接参照演算子を使用してアクセスすることはできません。これは、おそらくこれらのEXC_BAD_ACCESSエラーの原因です。構造体を使用し

+0

コンパイラはエラーをスローして、最初にビルドを防ぎました。だから、これは当てはまりません。 – gschandler

関連する問題