2013-04-04 83 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

相關問題