这个与上一篇的表达式求值都是iOS课程实验内容,老师演示了一个用NSExpression实现的版本,让我们用表达式求值的方式实现==
使用NSExpression实现
NSExpression是什么
基础的教程里并没有介绍这个,网上有关的中文介绍也比较少,有一篇NSHipster的文章,不过看完还是不怎么了解NSExpression,所以这块等稍后研究下官方文档后再补充。
思路
还是用MVC的模型.
先"画"出计算器的样子,一个比较简单的计算器,可以进行四则运算。
-
Model里面主要实现下面三个方法:
-(void)delNumber;//退格 -(NSString *)compute;//计算 -(void)clearSpace;//清空输入
最后,ViewController需要做的是,将用户键入的字符“拼装”成字符串,然后交给Model去处理。
需要注意的地方
-
初始化calculator的实例对象
在viewDidLoad中,视图控制器初始化的时候要确保生成calculator(Model)的实例对象:self.calculator = [[Calculator alloc]init];
-
覆盖calculator的getter方法
保证每次都能得到一个对象,而不是一个空指针-
(Calculator *)calculator
{ if (!_calculator) { _calculator = [[Calculator alloc]init]; } return _calculator; }
-
处理特殊字符
乘除按钮是用的特殊字符输入的,要进行计算的话需要转换成 * / 符号。
实现圆角
给按钮添加一点角度就可以变成圆角,关键是将这段修改的代码放在哪里?
利用viewWillAppear
在视图显示的时候利用awakeFromNib
新建一个类btnView,继承自UIButton,所以它可以覆盖awakeFromNib的方法。
每一次,按钮被唤醒的时候,都会被调用。将按钮的class改成btnView即可。
使用数值表达式实现
思路
可以直接利用之前的数值表达式的Model,所以要做的就剩两件事:一个是“画”计算器的界面,另一个就是“拼装”输入的字符串。
遇到的问题
在字符串末尾添加等号
由于我的Model设计的时候,要在表达式的末尾输入"="才能计算输出结果,所以在用户按下"="的时候,在将输入字符串input送入Model的ExpressionCalculate方法计算之前,在其末尾添加一个"="即可,这个"="可以直接从button的titleLabel获得。
NSMutableString *computeStr = [NSMutableString stringWithString:self.calculator.input];
[computeStr appendString:[[sender titleLabel] text]];
连续计算
最开始会发生连续计算失败的情况,比如,先输入10*10+20,计算得到120,如果再接着按下+10=x2即我想计算(120+10)x2计算结果是140而非260。
原因是textfield中的字符串虽然变了,但是calculator类中的input没有变,比如上面的式子,连续计算的话,input = 10x10+20+10x2 这样一个字符串。
修改的话就在每次计算完成后,将input的值改得跟textfiled里的值一样就可以了。
两次退格?
这是直接copy老师代码的后果==
在delNumber方法里面,将textfield里的字符删掉一个之后,又让input也调用了delNumber方法,而我每次计算之后又将input的值改得跟textfiled一样了,所以相当于退格了两次。
修改的话input不要再调用delNumber方法就可以了。
其它
特殊字符
减号上的'-'是通过插入特殊字符里的数学符号插入的,进行isEqualToString:的时候就不是运算用的'-'了,把它删了直接从键盘输入。
不过用NSExpression的话,不用改也没问题(这里也显示出NSExpression真心强大
待改进
非法输入的检查√
原来数值表达式模型中的输入检查会将"."也误判为非法运算符,我得再改改==
原来数值表达式中只考虑输入如英文字符等非法字符情况,由于在计算器中只允许输入数字和运算符,所以不合法的情况应该是输入连续的运算符,已有的方法isOperator可以用来判断,但要注意括号和其它运算符可以连续出现。
整数也有好多小数点√
为了够算定义的double类型,但是这样每次结果都带了好多0,小数就算了,整数结果也是这样,看着好心塞……
添加了判断是否为整数的方法,虽然很简单粗暴,but it works:将doubleValue和intValue相减,如果为0则为整数,否则就是浮点数==
希望好心人提供更好的idea。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。