1. 程式人生 > >Swift之旅:2.完成計算器,初探MVC設計模式

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方法:
  //用來進棧的資料
    var displayValue: Double{
        get{
            //將字串轉換為double
            return NSNumberFormatter().numberFromString(display.text!)!.doubleValue
        }
        set{
            //將value轉換成字串
            display.text = "\(newValue)"
            //設定重新開始輸入字串
            userIsInTheMiddleOfTypingANumber = false
        }
    }
其中NSNumberFormatter類中比較常用的兩個方法:

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