2010-06-10 46 views
0

我想在可可中做一個簡單的計算器應用程序。當我點擊我的一個按鈕時程序就會掛起。我想我已經追蹤,增加了一個數字,目前屏幕上的數字的問題到底出我的控制器的一部分:爲了讓可可指針幫助

- (void)updateNumber:(int)buttonClicked{ 
*self.activeNumberPointer = *self.activeNumberPointer * 10 + buttonClicked; 
[outputField setFloatValue:*self.activeNumberPointer]; 
} 

我用一個指針「activeNumber」我程序來分辨我正在編輯的兩個操作數中的哪一個。

任何幫助表示讚賞,謝謝。

(編輯):我的聲明和@財產:

//CalculatorController.h 
@interface CalculatorController : NSObject { 
    IBOutlet NSTextField *outputField; 
    float variable1, variable2; 
    float *variable1Pointer, *variable2Pointer; 
    float *activeNumberPointer; 
} 

float variable1 = 0; 
float variable2 = 0; 
float* variable1Pointer = &variable1; 
float* variable2Pointer = &variable2; 
float* activeNumberPointer = &variable1; 

@property (readwrite) float variable1, variable2; 
@property (readwrite) float *vairable1Pointer, *variable2Pointer; 
@property (readwrite) float *activeNumberPointer; 

... 

完整的XCode可用的文件位置:http://rapidshare.com/files/397664243/Calculator_2.zip (FYI:我實際使用leftNumberValue和rightNumberValue而不是在項目的變量1和變量2) 因爲我對於Objective-C和XCode而言,任何普遍的批評都是受歡迎的。

+0

爲什麼'activeNumberPointer'是一個指針? – zneak 2010-06-10 23:44:41

+0

它應該指向用戶編輯並顯示在'ouputField'上的'variable1'。當用戶點擊加,減,乘或除時,它會將'activeNumberPointer'更改爲'variable2'。當等號被點擊時,它對'variable1'和'variable2'進行必要的操作。我希望這能澄清我的問題。 – 2010-06-10 23:55:30

+0

如果你要添加聲明和'@ property'聲明,它會讓我們更容易。另外,'variable1'和'variable2'在哪裏,它們是ivars嗎? – 2010-06-11 00:28:35

回答

0

上的指針不清楚在Objective-C簡單的變量類型,而不是完全清楚你爲什麼使用指針的。

*self.activeNumberPointer = *self.activeNumberPointer * 10 + buttonClicked; 

您在此表達式的左側使用了*運算符(取消引用)錯誤。在做任務時,你不想像那樣解除引用。

http://www.cplusplus.com/doc/tutorial/pointers/

那是一個C++參考,但一個良好的開端指針邏輯。

我可能會使用NSMutableArray或類似的構造(你想存儲多於兩個數字嗎?),並使用整數索引指向屏幕上顯示的「當前」數字。

而且,我不知道,如果它的一個錯字,或一些缺碼等,但...

@interface CalculatorController : NSObject { 
    IBOutlet NSTextField *outputField; 
    float variable1, variable2; 
    float *variable1Pointer, *variable2Pointer; 
    float *activeNumberPointer; 
} 

float variable1 = 0; 
float variable2 = 0; 
float* variable1Pointer = &variable1; 
float* variable2Pointer = &variable2; 
float* activeNumberPointer = &variable1; 

...你似乎是宣告上述的接口定義爲所有的變量ivars - 或直接附加到您的CalculatorController的實例變量,然後在接口定義之外,您將它們重新聲明爲GLOBAL變量。沒有必要爲第二組的定義,如果你正在尋找初始化這些實例變量在實現

使用這些,通常有一個叫做-init,你可以重寫功能(因爲你是繼承NSObject的) ,其類似於其他語言的構造函數。這將存在於你的實現文件(.m或.mm)中。它可能是這個樣子:

-(CalculatorController *)init{ 
    if(self = [super init]){ 
     // Do your initialization here etc 
    } 
    return self; 
} 

還有另一個功能-awakeFromNib如果這是一個XIB/NIB文件中實例化的用戶界面定義的一部分,你可以重寫。當類和UI已經加載時,-awakeFromNib函數被調用。

編輯:明確指針業務.... self.activeNumberPointer = * self.activeNumberPointer * 10 + buttonClicked;

這是正確的。您不要在左側使用取消引用操作符,但是您在右側使用取消引用操作符,因爲您正在查找self.activeNumberPointer的值。

喬希

0

當你使用它們時,你不需要* self.activeNumberPointer或activeNumberPointer,就在你定義它們時。嘗試:

- (void)updateNumber:(int)buttonClicked{ 
self.activeNumberPointer = self.activeNumberPointer * 10 + buttonClicked; 
[outputField setFloatValue:activeNumberPointer]; 
} 
+2

中的'* self.activeNumberPointer = * self.activeNumberPointer * 10 + buttonClicked;'旁邊放置一個紅色箭頭是的,但是我不需要在指針前加*爲了獲得它指向的價值? – 2010-06-10 23:43:19

0
float variable1, variable2; 
    float *variable1Pointer, *variable2Pointer; 
    float *activeNumberPointer; 
} 

float variable1 = 0; 
float variable2 = 0; 
float* variable1Pointer = &variable1; 
float* variable2Pointer = &variable2; 
float* activeNumberPointer = &variable1; 

不能在類@interface內初始化實例變量。你在這裏實際上做了什麼是用這些名字中的每一個聲明兩個變量。

對於每個名稱,一個變量是一個實例變量,在緊跟在@interface之後的{...}內聲明,另一個是全局變量,在頭文件的其他地方聲明。具體而言,您在@interface中聲明瞭全局變量,但這並不重要:全局變量與任何類或對象都沒有關係,您可以在編譯器沒有異議的情況下將它們放入或不放入@interface

您初始化的全局指針變量指向全局變量float,但在@implementation的方法體中,實例變量級別高於全局變量(實例變量是一個範圍更窄)。而且,屬性總是基於實例變量,而不是全局變量。因此,在這些方法中,您指向(通過屬性)實例變量,而不是您初始化的全局變量。

實例變量在實例創建時被初始化爲nil,因此activeNumberPointer實例變量的值爲NULL。因此,像這樣的語句:

*self.activeNumberPointer = *self.activeNumberPointer * 10 + buttonClicked; 

讀取並寫入空指針。這是你看到的崩潰。

這也是值得指出的是這樣的:

*self.activeNumberPointer = … 

不是一個屬性賦值,這是說,它不會發送self一個setActiveNumberPointer:消息;它是屬性檢索(發送一條getter消息),它返回指針。這是值得削減的財產,以避免混淆兩者在這裏。

崩潰的解決方案是刪除全局變量並在代碼中初始化您的實例變量。這是init方法的用途。在the typical fashion中重寫init並在那裏設置您的初始指針值。在整個課程中直接訪問這些實例變量(無需通過屬性)。

更好的是,完全免去指針玩雜耍。當你需要用主動變工作

BOOL editingVariable2; 

測試布爾值:使用BOOL變量之間進行選擇。爲了不會在每次需要時都寫出麻煩的if-else語句,可以將其封裝到名爲setValueOfActiveVariable:switchActive:的方法中,該方法執行第一部分所述的操作,然後,如果第二部分的參數爲YES,則切換活動變量。

布爾變量解決方案將消除從此類完全訪問未初始化或無效更長的指針的風險。