斯坦福大学iOS应用开发教程学习笔记(第二课) 计算器实现(mvc实战)

news/2024/7/5 4:05:55


整个项目下载:https://github.com/junxianhu/Calculator,觉得有帮助的可以点击Star啊,谢谢啦。


界面不太好看  ==!


主要的文件目录如下:


贴几个关键的文件,其实注视都很详细,可以下载下来仔细看:


ViewController.h

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController

//为什么使用weak,因为UIlabel已经有个strong指针了,在父窗口view已经有strong指向它了,只需要它在view里面,所以weak //线程非安全
@property (weak, nonatomic) IBOutlet UILabel *display;

@end

ViewController.m

#import "ViewController.h"
#import "CalculatorBrain.h"

//private
@interface ViewController()
@property (nonatomic) BOOL userIsInTheMIdddlOfEnteringANumber;
//用来指向model
@property(nonatomic,strong) CalculatorBrain *brain;
@end


@implementation ViewController

@synthesize display= _display;
@synthesize userIsInTheMIdddlOfEnteringANumber = _userIsInTheMIdddlOfEnteringANumber;
@synthesize brain=_brain;

//延迟实例化
-(CalculatorBrain *)brain{
    if (!_brain) {
        _brain = [[CalculatorBrain alloc]init];
    }
    return _brain;
}


//IBAction:void 标记为action id:可以指向任何类型的指针
//更改id为UIButton类型即可
- (IBAction)digitPressed:(UIButton *)sender {
    
    NSString *digit =  [sender currentTitle];
    //NSLog(@"digit pressed = %@",digit);
    
//    UILabel *myDisplay = self.display;//[self display];
//    NSString *currentText = [myDisplay text];
//    NSString *newText = [currentText stringByAppendingString:digit];
//    myDisplay.text = newText;
//    上面4行精简一下代码为
//    self.display.text = [self.display.text stringByAppendingString:digit
    
    if (self.userIsInTheMIdddlOfEnteringANumber) {
        self.display.text = [self.display.text stringByAppendingString:digit];
    } else {
        self.display.text = digit;
        self.userIsInTheMIdddlOfEnteringANumber =  YES;
    }
}

//先按2个数字 然后按操作符
//所以这里按下操作符就是要计算结果了
- (IBAction)operationPressed:(UIButton *)sender {
    
    if (self.userIsInTheMIdddlOfEnteringANumber) {
        [self enterPressed];
    }
    //利用model计算结果,然后输出
    double result = [self.brain performOperation:sender.currentTitle];
    NSString *resultString = [NSString stringWithFormat:@"%g",result];
    self.display.text = resultString;
}

//按下enter键,就是入栈一个数字
- (IBAction)enterPressed {
    
    [self.brain pushOperation:[self.display.text doubleValue]];
    self.userIsInTheMIdddlOfEnteringANumber = NO;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

CalculatorBrain.h文件

#import <Foundation/Foundation.h>

@interface CalculatorBrain : NSObject

-(void)pushOperation:(double) operand;
-(double)performOperation:(NSString *)operation;

@end

CalculatorBrain.m 文件


#import "CalculatorBrain.h"

//private
@interface CalculatorBrain()

//初始化为nil或0
@property(nonatomic,strong) NSMutableArray *operandStack;

@end



@implementation CalculatorBrain
@synthesize operandStack = _operandStack;
//只有一个变量指针 不分配内存空间

-(NSMutableArray *)operandStack{
    
    //延迟实例化
    if(_operandStack == nil){
        _operandStack = [[NSMutableArray alloc] init];
    }
    return _operandStack;
}

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

//入操作数
-(void)pushOperation:(double) operand{
    //add只能加入对象
    [self.operandStack addObject:[NSNumber numberWithDouble:operand]];
}

//出栈操作数
-(double)popOperand{
    
    NSNumber *operandObject = [self.operandStack lastObject];
    //数组为空 删除会崩溃
    if (operandObject != nil) {
        [self.operandStack removeLastObject];
    }
    return [operandObject doubleValue];
}

-(double)performOperation:(NSString *)operation{
    
    double result = 0;
    
    if ([operation isEqualToString:@"+"]) {
        result =[self popOperand] + [self popOperand];
    }else if ([operation isEqualToString:@"/"]){
        
        double tmp2 = [self popOperand];
        double tmp1 = [self popOperand];
        if (tmp2 != 0) {
            result = tmp1 / tmp2;
        }
    }else if([operation isEqualToString:@"*"]){
        result = [self popOperand] * [self popOperand];
    }else if([operation isEqualToString:@"-"]){
        double tmp2 = [self popOperand];
        double tmp1 = [self popOperand];
        result = tmp1 - tmp2;
    }
    
    //结果入栈
    [self pushOperation:result];
    return result;
}


@end


http://www.niftyadmin.cn/n/4121157.html

相关文章

NDK mk 文件分析

通过分析一个例子来了解NDK makefile文件的生成。例子"hello JNI" &#xff0c;由NDK提供的例子 A. 目录结构 jni目录&#xff1a;包含本地源文件&#xff0c;eg&#xff1a;jni/hello-jni.c&#xff0c;该源文件实现了一个简单的共享库&#xff0c;实现了一个简单的…

哈佛告诉你

陈祖芬 哈佛某教授对学生说&#xff0c;你学我这门课&#xff0c;你就一天只能睡两小时。学生想&#xff0c;那么&#xff0c;我学四门课&#xff0c;我就没有睡眠时间了&#xff0c;我就得倒贴睡眠时间了。 于是—— 哈佛产的诺贝尔奖得主有33位。 哈佛产的美国总统有7位。…

中国武侠片经典剧情(^.^)

为什么80%的码农都做不了架构师&#xff1f;>>> 从小到大&#xff0c;可以说&#xff0c;我是一直看着中国武侠片长大的&#xff0c;中国武侠&#xff0c;确实有着自己的风格和传统&#xff0c;在世界影坛也有一定的地位&#xff0c;甚至有的国外朋友曾经问过我说&…

Activity LifeCycle 生命周期

1. Android中Activity的调用机制 据我的了解&#xff0c;Android中Activity跳转的实现&#xff0c;主要是通过栈的先进后出的原理设计的。当新建一个Activit的时候&#xff0c;把它压入栈&#xff0c;然后按返回键的时候&#xff0c;就出栈。android设置了容纳Activity栈的大小…

关于LUN、PV、VG和LV

1.划分LUN LUN只是一个逻辑的东西。在存储设备内部&#xff0c;LUN与物理硬盘的关系&#xff0c;如同主机中逻辑卷与物理硬盘的关系&#xff0c;也就是好像LV和PV的关系&#xff0c;在不同范畴。可以理解为LUN就是在做完RAID之后的逻辑盘上分出来的logic driver。 但不同的是&a…

重构:第一个案例

在写重构的学习笔记之前&#xff0c;首先我们需要向伟大的软件设计师Martin Fowler致敬&#xff0c;是他带给了我们重构的思想&#xff0c;敏捷的思想。 重构--改善既有代码的设计。意味着对现有运行中的代码进行新的修改、设计。这对很多项目经理来说是不可思议的&#xff0c;…

敏捷开发 慨叙

在开始写敏捷开发系列博客时&#xff0c;首先感谢伟大的软件设计师Martin Fower以及其他几位敏捷思想的创建人&#xff0c;是他们带给了我们新的编程思想&#xff0c;解决了毕业几年来一直困恼我的很多问题。 软件开发是一种对人类智慧的管理&#xff0c;对人大脑思维的“工厂化…

An ATL Sample using VS2005

An ATL Sample using VS2005<?xml:namespace prefix o ns "urn:schemas-microsoft-com:office:office" />1. Create an ATL COM1). Start VS2005, new a project, select “Visual C”->”ATL”->”ATL Project”, specify the name(“SimonAT…