0

这是一个加法计算器的代码,它通过先输入两个操作数再输入运算来进行运算;像“5 enter 2 enter +”会导致“7”。当用户点击一个数字时,adouble将被发送到pushOperand:当用户点击添加按钮时,字符串@"+"将被发送至performOperation:。我的问题是制作这些副本有什么意义?program如果runProgram:它们都是浅拷贝,并且它们的元素最终都指向 , 和 , 的相同元素NSNumberNSString对象?_programStackprogramstack

#import <Foundation/Foundation.h>

@interface CalculatorBrain : NSObject
@property (nonatomic, readonly) id program;

+(double)runProgram:(id)program; 
-(double)performOperation:(NSString *)operation;

@end

#import "CalculatorBrain.h"     

@interface CalculatorBrain ()
@property (nonatomic, strong) NSMutableArray *programStack;
@end

@implementation CalculatorBrain
@synthesize programStack = _programStack;

-(NSMutableArray *) programStack {
    if (!_programStack)
        _programStack = [[NSMutableArray alloc] init];
    return _programStack;
}

-(void)pushOperand:(double)operand {
    [self.programStack addObject: [NSNumber numberWithDouble: operand]];
}

-(double)performOperation:(NSString *)operation {
        [self.programStack addObject: operation];
        double result = [CalculatorBrain runProgram: self.program];
        return result;
    }

-(id)program {
    return [self.programStack copy];
}

+(double)runProgram:(id)program {
    NSMutableArray *stack;
    if ([program isKindOfClass: [NSArray class]])
        stack = [program mutableCopy];
    return [self popOperandOffProgramStack: stack];
}

+(double)popOperandOffProgramStack:(NSMutableArray *)stack {
    double result = 0;
    id topOfStack = [stack lastObject];
    if (topOfStack)
        [stack removeLastObject];

    if ([topOfStack isMemberOfClass: [NSNumber class]])
        result = [topOfStack doubleValue];

    if ([topOfStack isKindOfClass: [NSString class]]) {
        NSString *operation = topOfStack;

        if ([operation isEqualToString: @"+"]) {
            result = [self popOperandOffProgramStack: stack] + [self popOperandOffProgramStack: stack];
    }
    return result;
} 
@end
4

1 回答 1

0

NSNumber并且NSString是不可变的,因此制作无法更改的对象集合的浅表副本是安全的。

program重要的是返回一个副本而programStack不是实际的可变数组。这是因为programStack它是在类扩展中声明的私有内部属性,因此它在外部不可见。如果您programStack直接返回外部用户可以更改它,因为它是一个NSMutableArray. 该program方法返回一个,NSArray因为可变对象的副本是不可变的,它具有正确的语义。您想为外部用户提供programStack数组的快照,而不是访问您的类内部。

runProgram情况不同。外部用户将CalculatorBrain一个传递NSArray给进程,并且类的内部逻辑要求堆栈在处理时从数组中弹出元素。因此,您需要制作 amutableCopy以便可以对其进行变异以进行处理。

于 2012-08-25T03:16:11.083 回答