2012-03-24 10 views
0

上記のエラーメッセージをコンパイルして終了するプログラムがあります。スレッド1:EXC_BAD_ACCESS(コード= 13、アドレス= 0x0)

ここには0 objc_msgSendログがあります。行をコメントアウトしているエラーメッセージが表示されます上:

libobjc.A.dylib`objc_msgSend: 
0x7fff8c9b7e80: testq %rdi, %rdi 
0x7fff8c9b7e83: je  0x00007fff8c9b7eb0  ; objc_msgSend + 48 
0x7fff8c9b7e85: testb $1, %dil 
0x7fff8c9b7e89: jne 0x00007fff8c9b7ec7  ; objc_msgSend + 71 
0x7fff8c9b7e8c: movq (%rdi), %r11 
0x7fff8c9b7e8f: pushq %rax 
0x7fff8c9b7e90: movq 16(%r11), %r10 
0x7fff8c9b7e94: movl %esi, %eax 
0x7fff8c9b7e96: andl (%r10), %eax   // error message arrow appears on this line 
0x7fff8c9b7e99: movq 16(%r10,%rax,8), %r11 
0x7fff8c9b7e9e: incl %eax 
0x7fff8c9b7ea0: testq %r11, %r11 
0x7fff8c9b7ea3: je  0x00007fff8c9b7edb  ; objc_msgSend + 91 
0x7fff8c9b7ea5: cmpq (%r11), %rsi 
0x7fff8c9b7ea8: jne 0x00007fff8c9b7e96  ; objc_msgSend + 22 
0x7fff8c9b7eaa: popq %rax 

// Rest left out; no error messages 

main.m:

#import <Foundation/Foundation.h> 
#import "Budget.h" 

#import "Transaction.h" 
#import "CashTransaction.h" 
#import "CreditCardTransaction.h" 

int main(int argc, const char * argv[]) 
{ 

    Budget *europeBudget = [Budget new]; 
    [europeBudget createBudget:1000.00 withExchangeRate:1.2500]; 

    Budget *englandBudget = [Budget new]; 
    [englandBudget createBudget:2000.00 withExchangeRate:1.5000]; 


    NSMutableArray *transactions = [[NSMutableArray alloc]initWithCapacity:10]; 
    Transaction *aTransaction; 
    for (int n=1; n < 2; n++) { 

     [aTransaction createTransaction:n * 100 forBudget:europeBudget]; 
     [transactions addObject:aTransaction]; 
     aTransaction = [CashTransaction new]; 
     [aTransaction createTransaction:n * 100 forBudget:englandBudget]; 
     [transactions addObject:aTransaction]; 
    } 

    int n = 1; 
    while (n < 4) { 

     [aTransaction createTransaction:n * 100 forBudget:europeBudget]; 
     [transactions addObject:aTransaction]; 
     aTransaction = [CreditCardTransaction new]; 
     [aTransaction createTransaction:n * 100 forBudget:englandBudget]; 
     [transactions addObject:aTransaction]; 
     n++; 
    } 


     for (Transaction * aTransaction in transactions) { 
      [aTransaction spend]; 
    } 


      return 0; 
} 

Transaction.h

輸入

予算@class

@interface Transaction : NSObject 
{ 
    Budget *budget; 
    double amount; 
} 

- (void) createTransaction:(double)theAmount forBudget:(Budget*) aBudget; 
- (void) spend; 
- (void)trackSpending: (double) theAmount; 

@end 

Transaction.m

#import "Transaction.h" 
#import "Budget.h" 

@implementation Transaction 

- (void) createTransaction:(double)theAmount forBudget:(Budget*) aBudget 
{ 
    budget = aBudget; 
    amount = theAmount; 
} 

- (void) spend 
{ 
    // Fill in the method in subclasses 
} 

-(void)trackSpending: (double) theAmount 
{ 
    NSLog(@"You are about to spend another %.2f", theAmount); 
} 
@end 
+0

私が間違っている場合は私を修正しますが、0x0はNULLの場合は16進数です。私はあなたがnullオブジェクトをメッセージしていると思います。 – CodaFi

+0

NSMutableArrayオブジェクトにあるかもしれませんが、NSMutableArrayオブジェクトが見つかりませんでした。あなたの熟読のためにmain.mファイルを追加しました。 – pdenlinger

+2

メッセージをnilオブジェクトに送信するのはまったく問題ありません。これは、コンパイラが関数の戻り値の型にキャストするゼロを返します。 (これはNSRectという戻り値の型で問題ですが、新しいバージョンのSDKが正しく処理しています)objc_messageSendのクラッシュは通常、解放されたオブジェクトにメッセージを送信していることを意味します。 – davehayden

答えて

2

aTransactionは、それが宣言されていた値が割り当てられていないので、ゴミ値で始まります。ループをはじめて、そのゴミ値にメッセージを送ります:クラッシュ!

Transaction *aTransaction = nil; 
+0

質問:Transactionクラスには、2つのインスタンス変数BudgetとAmountがあります。デフォルトのivarsがenum関数に設定されていると、クラッシュするのはなぜですか?私はあなたのレビューのTransaction.h、.mファイルを追加しました。コードを "Transaction * aTransaction = nil;"に変更しました。しかし、私はクラッシュしました。スレッド1を得ました:[トランザクションaddObject:aTransaction]でシグナルSIGABRTメッセージ。行 – pdenlinger

+0

「enum関数」の意味を理解できません。あなたがトランザクションを初期化しているのであれば、コード内に明らかに間違ったことはありません。 NSZombieEnabledを有効にしてください(その手順についてはGoogleをご覧ください)。 – davehayden

+0

遅れて申し訳ありませんが、私はちょうど同じエラーを持っているかどうかを確認するために、もう一度コーディングしてみました。 enum関数の場合、私はループを意味しました。 NSZombie Enabledを有効にすることで何がわかるのでしょうか。 – pdenlinger

6

私はSIGSEGVの周りに別の問題への解決策を探していた間、私はこの問題に上陸した:nilに初期値で変数を宣言すると、問題を解決します。

少し遅れていますが、ドキュメントと完全性のためにこの質問にお答えしたいと思います。

メッセージをインスタンス化せずにオブジェクトに送信するため、問題が発生します。次のように私はこれらのメソッドを記述します

- (void) createTransaction:(double)theAmount forBudget:(Budget*) aBudget; 

Transaction *aTransaction; 
for (int n=1; n < 2; n++) { 

    [aTransaction createTransaction:n * 100 forBudget:europeBudget]; 

及び作成方法は以下のように定義されました。

まず、createTransactionは私にとってはファクトリメソッドのように聞こえます。

+(Transaction *) createTransactionWithAmount:(double) theAmount forBudget: (Budget *) aBudget; 

は、その後、私は以下のようにそのファクトリメソッドを使用します:だから、私はそれがクラスメソッドのようになるだろう

1:コードと2つの問題を修正する必要があり

for (int n=1; n < 2; n++) { 
    Transaction *aTransaction = [Transaction createTransactionWithAmount: n*100 forBudget: europeBudget]; 
    // [aTransaction createTransaction:n * 100 forBudget:europeBudget]; 
    [transactions addObject:aTransaction]; 

)あなたは常にaTransactionとして定義されたメッセージを送信するインスタンスを持ちます。var
2)このオブジェクトをコレクションに追加する心配はありません。これはもはやゼロにならないためです。

関連する問題