2010-06-10 87 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,则切换活动变量。

布尔变量解决方案将消除从此类完全访问未初始化或无效更长的指针的风险。