Swift之旅:2.完成計算器,初探MVC設計模式
斯坦福大學公開課:iOS8
github上字幕連結:字幕 百度網盤資源下載連結:百度網盤1.計算器完成
①回車鍵及相關的程式碼//定義一個數組,用來當做棧儲存資料使用 var openStack = Array<Double>(); //enter用來執行進棧操作 @IBAction func enter() { //設定重新開始輸入字串 userIsInTheMiddleOfTypingANumber = false //將value進棧 openStack.append(displayValue) println("openStack = \(openStack)") }
這裡面的displayValue定義其get和set方法:
其中NSNumberFormatter類中比較常用的兩個方法://用來進棧的資料 var displayValue: Double{ get{ //將字串轉換為double return NSNumberFormatter().numberFromString(display.text!)!.doubleValue } set{ //將value轉換成字串 display.text = "\(newValue)" //設定重新開始輸入字串 userIsInTheMiddleOfTypingANumber = false } }
func stringFromNumber(number:NSNumber) -> String? NSNumber 轉換成String
func numberFromString(string:String) -> NSNumber? String 轉漢城 NSNumber
NSNumberFormatter().numberFromString(display.text!)!.doubleValue將字串轉換為NSnumber,然後將NSNumber轉換為Double。
NSNumberFormatter
②加減乘除開根號運算
//用來進行運算
@IBAction func operate(sender: UIButton) {
//獲得當前按鈕的title
let operation = sender.currentTitle
//如果是中間輸入的數字
if userIsInTheMiddleOfTypingANumber {
//進棧
enter()
}
//switch判斷是什麼運算子,然後進行相應的運算
switch operation! {
case "×":performOperation(multiply)
case "÷":performOperation({(op1:Double, op2:Double)->Double in return op1 / op2;})
case "+":performOperation({(op1, op2) in op1 + op2;})
case "−":performOperation{$0 - $1}
case "√":performOperation{sqrt($0)}
default:break
}
}
//定義一個方法用來進行加減乘除運算,引數型別是一個方法:(Double, Double)->Double
private func performOperation(operation: (Double, Double)->Double) {
//棧中必須有兩個元素才能進行加減乘除的運算
if openStack.count >= 2 {
//把最後的兩個元素分別出棧,然後進行運算
displayValue = operation(openStack.removeLast(),openStack.removeLast())
enter()
}
}
//定義一個方法用來開平方,引數型別是一個方法:Double->Double
private func performOperation(operation: Double->Double) {
//棧中必須多於一個元素才能進行開平方
if openStack.count >= 1 {
displayValue = operation(openStack.removeLast())
enter()
}
}
①Swift中可以將一個方法作為另一個方法的引數:
performOperation(multiply)是將multiply方法作為performOperation方法的引數
②Swift中可以隱式的將一個方法作為另一個方法的引數
performOperation( {(op1:Double, op2:Double)->Doubleinreturn op1 + op2;})
可以看到隱式方法作為引數的時候,要放在{}裡面,稱之為閉包
in後面表示方法內部的操作③Swift有型別自動推導的功能,所以可以簡寫為:
performOperation( {(op1, op2)in op1 + op2;})
④Swift中編譯器會自動給方法中的引數傳一個預設值,第一個引數$0,第二個引數$1........所以可以繼續簡化為:performOperation({ $0 + $1})
⑤Swift中如果一個方法是另外一個方法的最後一個引數,那麼可以將此方法放到原方法後面:
performOperation(){ $0 + $1}
方法中無引數了可以直接去掉():performOperation(){$0
+ $1}
這裡要重點解釋一下方法過載問題:
Swift語言支援方法過載,OC不支援方法的過載:
func performOperation(operation: (Double,Double)->Double)
func performOperation(operation:Double->Double)
這兩個方法,名稱一樣,但是引數個數不一樣,屬於方法過載。如果按照課程上說的,直接這麼用會出現問題。錯誤提示:Method 'perform' with Objective-C selector 'perform: ' conflicts with previous declaration with the same Objective-C selector
原因是:這個類繼承自UIViewController,也繼承NSObject,編譯器於是會按照OC中屬性的約束來編譯,所以就會報錯。
修改這個錯誤方法很簡單:
1.將兩個函式的名字取不一樣
2.用一個OC不支援的型別來阻止Swift語言的編譯器按照OC方式揭發這個錯誤。
2.MVC設計模式初探
解釋一下:
1.綠色的箭頭表示Controller對Model和View的直接引用。直接引用很簡單,只需要在Controller中定義Model和View的例項變數。如果是通過storyboard或者xib定義View,則有IBOutlet。
2.View向Controller通訊有三種方式(三個黃色箭頭):
①action對應target。例如UIButton中的Touch down,action(點選按鈕) target新增方法。
②設定View的delegate(代理),如UITabViewDelegate,在Controller中實現代理。
③設定View的data source(資料來源), 如UITableViewDataSource。
這樣View達到了既能向Controller通訊,又不需要知道具體的Controller是誰是目的,這樣就和Controller解耦了。
3.Model圖形上面有一個訊號塔,旁邊寫著Notification & KVO。Model主要是通過通知和鍵值監聽來和Controller通訊的。
4.Controller在MVC可以和View和Model相互通訊,但是Model和View之間無法通訊,用黃線隔開。
===============================================================================================================================
Demo:http://download.csdn.net/detail/misakahina/8824853