這個與上一篇的表達式求值都是iOS課程實驗內容,老師演示了一個用NSExpression實現的版本,讓咱們用表達式求值的方式實現==ios
基礎的教程裏並無介紹這個,網上有關的中文介紹也比較少,有一篇NSHipster的文章,不過看完仍是不怎麼了解NSExpression,因此這塊等稍後研究下官方文檔後再補充。express
仍是用MVC的模型.app
先"畫"出計算器的樣子,一個比較簡單的計算器,能夠進行四則運算。ide
Model裏面主要實現下面三個方法:idea
-(void)delNumber;//退格 -(NSString *)compute;//計算 -(void)clearSpace;//清空輸入
最後,ViewController須要作的是,將用戶鍵入的字符「拼裝」成字符串,而後交給Model去處理。spa
初始化calculator的實例對象
在viewDidLoad中,視圖控制器初始化的時候要確保生成calculator(Model)的實例對象:設計
self.calculator = [[Calculator alloc]init];
覆蓋calculator的getter方法
保證每次都能獲得一個對象,而不是一個空指針指針
(Calculator *)calculatorcode
{ 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。