在此程序中浅层复制

时间:2012-08-25 02:17:34

标签: objective-c

这是来自加法计算器的代码,通过首先输入两个操作数然后输入操作来执行操作;像“5输入2输入+”将导致“7”。当用户点按某个号码时,double将被发送到pushOperand:当用户点按添加按钮时,字符@"+"将被发送到performOperation:。我的问题是,如果这些副本都是浅层副本,那么在programrunProgram:制作这些副本的重点是什么,它们的元素最终都指向NSNumber和{{NSString 1}}对象为_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

1 个答案:

答案 0 :(得分:0)

NSNumberNSString是不可变的,因此制作一个无法改变的对象集合的浅表副本是安全的。

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

CalculatorBrain中,情况有所不同。外部用户将NSArraymutableCopy传递给进程,并且类的内部逻辑要求堆栈在处理时从阵列中弹出元素。因此,您需要创建一个{{1}},以便可以对其进行变异处理。