1

据我了解,self 指的是当前类,当我在 self 之后使用一个点时,就是使用它的一个属性。在这里的代码中有一个用途self.popOperand,我不明白 popOperanad 是否不是属性。我不明白的另一件事是为什么 [self pushOperand:result];有效而[self.pushOperand:result];无效。

#import "Calcbrain.h"
@interface Calcbrain()

@property (nonatomic,strong) NSMutableArray *operandStack;


@end


@implementation Calcbrain
@synthesize operandStack  = _operandStack;

-(NSMutableArray *) operandStack
{
    if(_operandStack == nil) _operandStack = [[NSMutableArray alloc]init];
    return _operandStack;
}
-(double)popOperand
{
    NSNumber *objectNum = [self.operandStack lastObject];
    if (objectNum)[self.operandStack removeLastObject];
    return [objectNum doubleValue];

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

-(void)pushOperand:(double)opernand
{
    [self.operandStack addObject:[NSNumber numberWithDouble:opernand]];

}
-(double)performOperation:(NSString *)operation
{
    double result=0;

    if([operation isEqualToString:@"+"])
    {
        result = self.popOperand + self.popOperand;
    }
    else if ([@"*" isEqualToString:operation])
    {
        result = self.popOperand * self.popOperand;
    }
    [self pushOperand:result];

    return result;
}


@end
4

3 回答 3

3

虽然该.符号主要用于属性,但它可以用于返回值的无参数方法。为什么?因为属性的合成 getter 是相同的形式。

-(double)calcValue {
    ....
    return value;
}

相当于属性声明:

@property (nonatomic, readonly) double calcValue;

虽然可能没有属性声明,但这并不意味着.不能使用该符号。编译器将在编译时有效地将.符号更改为方法调用,就像语法糖.的一种形式一样。如此:

self.popOperand
// Translates to
[self popOperand];

这导致第 2 部分,为什么不起作用[self.pushOperand:result];?原因是.不支持直接传递参数。

将参数分配/推送到属性的唯一方法是 via self.pushOperand = result,但这不起作用,因为符号分配映射到的对应- (void)setPushOperand:(double)pushOperand;.没有。

[self pushOperand:result];有效,因为您在调用特定方法时是明确的,称为pushOperand:.

总体而言,.仅保留属性的符号,如果您使用的方法并非设计为“属性”,请明确说明。

Update: self是一个保留关键字,它表示指向我们当时正在工作的实例的指针。

例如,我可以Calcbrain 在 Calcbrain 之外创建两个实例,例如 BrainViewController

Calcbrain* instance1;
Calcbrain* instance2;

现在,Calcbrain在其中声明了方法,让我们-(double)performOperation:(NSString *)operation用作示例。现在,如果我想从 BrainViewController 调用它,我会这样做:

[instance1 performOperation:@"+"];
[instance2 performOperation:@"+"];

因为我们正在调用一个属于另一个类的方法,所以我必须确定我创建的正确实例来引用它(即instance1instance2)。但是我如何从类本身中调用它,并确保它适用于正确的实例?我创建的实例不知道我创建的其他实例。使用self. self允许您在方法中引用自己。因此,如果我想performOperationCalcbrain自身内部,我需要使用 self:

[self performOperation:@"+"];
于 2012-11-01T12:29:55.273 回答
2

“点”只是一个语法糖,即使没有声明的属性也可以使用。表达方式

a.someProperty

相当于

[a someProperty]

和表达式

a.someProperty = c

相当于

[a setSomeProperty:c]

因此,self.popOperand与 是一样的[self popOperand]。在一些荒谬的情况下,也可以使用“点”,例如[NSMutableArray alloc].init.


非常不鼓励对非属性使用“点”语法。如果我是这段代码的维护者,我会全部改self.popOperand[self popOperand]以避免混淆。

(顺便说一句,没有定义+首先评估哪一方。更好的改变

result = [self popOperand] + [self popOperand]

double operand1 = [self popOperand]
double operand2 = [self popOperand]
result = operand1 + operand2;

-当您定义and时,这将是一个麻烦/。)

于 2012-11-01T12:28:46.617 回答
0

点用于访问类的属性。您还可以访问不带点的属性和方法:

[classInstance someMethodOrProperty];

此代码:等[classInstance someProperty];于此代码classInstance.someProperty;您不能调用带有点之类的属性的方法。

于 2012-11-01T12:30:48.303 回答