2012-03-24 96 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爲十六進制。我想你是在傳遞一個空對象。 – CodaFi 2012-03-24 18:13:44

+0

認爲它可能位於NSMutableArray對象中,但找不到它。已經添加了main.m文件供您閱讀。 – pdenlinger 2012-03-24 18:26:40

+2

發送消息給一個無對象是完全沒問題的。它返回零,編譯器將其轉換爲函數的返回類型。 (這是一個問題,如果你的返回類型是NSRect,但是新版本的SDK可以正確處理,正如我所記得的那樣。)objc_messageSend中的崩潰通常意味着你正在向釋放的對象發送消息。 – davehayden 2012-03-24 18:29:07

回答

2

aTransaction未分配時,它的聲明價值,所以它有一個垃圾值開出。通過循環第一次,你發送一條消息給那個垃圾值:崩潰!具有零初始值聲明的變量將解決這個問題:

Transaction *aTransaction = nil; 
+0

問題:Transaction類有兩個實例變量:預算和金額。如果默認的ivars在枚舉函數中被填充,它爲什麼會崩潰?我已經添加了Transaction.h,.m文件供您查看。將代碼更改爲「Transaction * aTransaction = nil;」但我碰到了。在[transactions addObject:aTransaction]上獲得了線程1:SIGABRT信號;行 – pdenlinger 2012-03-24 19:17:12

+0

我不確定你的意思是「枚舉函數」。如果您正在初始化aTransaction,我在代碼中看不到任何明顯的錯誤。嘗試開啓NSZombieEnabled(谷歌的方向),看看它說什麼。 – davehayden 2012-03-25 00:16:06

+0

抱歉,延遲響應;我只是試圖從頭開始重新編碼,看看我是否得到了同樣的錯誤,而且我做到了。對於枚舉函數,我的意思是循環。通過啓用NSZombie Enabled將會看到我能找到的東西。 – pdenlinger 2012-03-26 19:41:47

6

我在這個問題上降落,而我一直在尋找一個解決方案,圍繞SIGSEGV另一個問題。

雖然有點遲,但爲了文件和完整性,我想回答這個問題。

問題的產生是因爲您發送消息給對象而沒有實例化一個對象。

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

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

和創建方法被定義爲:

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

如下我會寫這些方法。

首先,createTransaction聽起來像是一種工廠方法。所以,我想使它成爲一個類的方法,如:

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

然後我會使用工廠方法如下圖所示:

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

這應該可以解決2個問題的代碼:

1 )您將始終有一個實例來發送消息,以定義爲aTransaction var
2)您不必擔心將此對象添加到集合中,因爲它不會再是零。

相關問題