2013-04-04 39 views
0

我正在通过斯坦福大学的iTunesU程序学习iOS开发。我遇到了一个意想不到的问题。为什么我必须使用自我。以引用自己的对象

我已经添加了一个明确的方法,但我得到这个错误 //使用未声明的标识符'operandStack';你的意思是'_operandStack'?

我知道我可以用[self.operandStack解决问题...等,而不是[operandStack

为什么需要自我?这不是暗示吗?为什么在引用_operandStack时不需要使用self?

#进口 “CalculatorBrain.h”

@interface CalculatorBrain() 
//string because we are the only ones interested 
@property (nonatomic, strong) NSMutableArray *operandStack; 
@end 



@implementation CalculatorBrain 

@synthesize operandStack = _operandStack; 

- (void) setOperandStack:(NSMutableArray *)operandStack 
{ 
    _operandStack = operandStack; 
} 

- (NSMutableArray *) operandStack 
{ 
    if(_operandStack==nil) _operandStack = [[NSMutableArray alloc] init]; 
    return _operandStack; 
} 

- (void) pushOperand:(double)operand 
{ 
    NSNumber *operandObject = [NSNumber numberWithDouble:operand]; 


    [self.operandStack addObject:operandObject]; 

} 

- (double) popOperand 
{ 
    NSNumber *operandObject = [self.operandStack lastObject]; 

    if (operandObject !=nil) 
    { 
     [self.operandStack removeLastObject]; 
    } 
    return [operandObject doubleValue]; 
} 

- (void) clear 
{ 
    //clear everything 
    [operandStack removeAllObjects]; 

// * ** * ** * ** * ** * ** * * * * ** * ** * ** //使用未声明的标识符'operandStack';你的意思是'_operandStack'?

} 

- (double) performOperation:(NSString *)operation 
{ 
    double result =0; 
    //calculate result 
    if ([operation isEqualToString:@"+"]) { 
     result = [self popOperand] + [self popOperand]; 
    } else if ([operation isEqualToString:@"*"]) { 
     result = [self popOperand] * [self popOperand]; 
    } else if ([operation isEqualToString:@"π"]) { 
     [self pushOperand:3.14159]; 
     NSNumber *operandObject = [self.operandStack lastObject]; 
     return [operandObject doubleValue]; 
    } 
    [self pushOperand:result]; 
    return result; 
} 
@end 
+1

继续操作前再次看课。他们对此非常清楚,你应该掌握setter/getters的概念与实例变量,并让自己适应整个课程中始终使用的懒惰实例。 – Mario 2013-04-04 19:27:17

+0

懒惰的实例化非常简单。我非常了解getter和setter以及实例变量。我所理解的是,我们需要在引用实例方法或属性时使用self,并且我们不需要为_operandStack使用self。在我的C#/ .net背景中,它总是指向当前实例,并可用于访问实例中可访问的任何对象。 – user1060500 2013-04-08 15:49:44

回答

4

因为你已经合成它(注意:在较新的目标C版本的合成是自动的):

@synthesize operandStack = _operandStack; 

这意味着你产生getter和setter,并选择以访问属性称它_operandStack。如果您想将它命名operantStack其更改为:

@synthesize operandStack; 

相反,如果你使用self.operandStack,您使用的是财产,而不是一个合成产生的的getter/setter。

使用合成和非合成属性是不同的,没有像许多人认为的访问属性的“推荐方式”,它们只是有不同的含义。例如:

- (void) setOperandStack:(NSMutableArray *)operandStack 
{ 
    _operandStack = operandStack; 
} 

您必须使用合成属性,否则将进入无限循环。合成属性是自动生成的,非合成属性也是自动生成的,但它可以被覆盖,就像你在那种情况下那样,它也可以在外部访问。

+0

我即将给出这个答案:) +1。 – x4h1d 2013-04-04 14:49:39

+2

可能需要稍作澄清。 _operandStack(或者“@synthesize operandStack”时的operandStack)不是一个访问器,而是一个实例变量。所以前缀与自身的区别在于调用getter和直接访问实例变量的区别。 – aLevelOfIndirection 2013-04-04 15:04:46

+0

'_operandStack'是对伊娃的直接引用(在上面的例子中)。 '@ synthesize'(通常)会创建两个访问器:' - (void)setOperandStack:(NSMutableArray *)'和 - (NSMuableArray *)operandStack'。 “self.operandStack”的使用将根据它是在左侧(LHS)还是在赋值操作的右侧使用相应的访问器。由于隐含地实现了将要合成的访问器,因此将使用隐式版本。合成方法确实会导致它创建一个隐含的ivar名称_operandStack。 – bshirley 2013-04-04 16:04:04

相关问题