Swift筆記-讓你2小時學會Swift

過年不能閒着,一邊學習Swift,一邊寫筆記,相信在有必定其餘語言基礎的狀況下用1.5小時看完該文章便可掌握。而後再花30分鐘打開XCode寫個Demo.
生命中拿出2小時來認識一門語言,很值吧!
筆記共分爲兩部分,一Swift基礎知識,二使用Xcode開發一個軟件
[TOC]程序員

swift基礎知識

變量和常量

//定義變量
var myVariable = 123

//定義常量
let myConstantVariable = 123

// 隱式指定整數類型
var anInteger = 2

// 明確指定整數類型
let anExplicitInteger :Int = 2

元組

let aTuple = (1, "Yes")
let anotherTuple = (aNumber: 1, aString: "Yes")
let theOtherNumber = anotherTuple.aNumber  // = 1

其餘用法golang

let http404Error = (404, "Not Found")
let (statusCode, statusMessage) = http404Error
print("The status code is \(statusCode)")

更多用戶函數返回值,返回兩個以上的值,跟golang很像swift

數組

var arrayOfIntegers : [Int] = [1,2,3]
// 隱式指定
var implicitArrayOfIntegers = [1,2,3]

// 也能夠建立空數組,但必須提供其類型
let anotherArray = [Int]()

//使用 append 函數向數組的末尾追加對象
myArray.append(4)

//數組中的任意位置插入對象
myArray.insert(5, atIndex: 0)

字典

字典是一種將鍵映射到值的類型,相似Java的Map,PHP的數組數組

var crew = [
          "Caption": "Jean-Luc Picard",
          "First officer": "William Riker",
          "Second Officer": "Data"
];


crew["Captain"]
// = "Jean-Luc Picard"

控制流

if

if 1+1 == 2 {
         println("The math checks out")
}

for-in

let loopingArray = [1,2,3,4,5]
var loopSum = 0
for number in loopingArray {
     loopSum += number
}
loopSum // = 15
var firstCounter = 0
     for index in 1 ..< 10 {
         firstCounter++
     }
// 循環9次

var secondCounter = 0
for index in 1 ... 10 { // 注意是三個句點,不是兩個
         secondCounter++
     }
// 循環10次

var sum = 0
for var i = 0; i < 3; i++ {
    sum += 1 
}
sum // = 3

while

var countDown = 5
while countDown > 0 {
     countDown--
}
countDown // = 0
var countUP = 0
do {
         countUp++
} while countUp < 5
countUp // = 5

if-let

能夠用 if-let 語句檢查一個可選變量是否包 含值。若是包含,則將這個值指定給一個常量變量,而後運行某段代碼。這樣能夠減小很 多行代碼,同時又可以保證安全性安全

var conditionalString : String? = "a string"
     if let theString = conditionalString? {
         println("The string is '\(theString)'")
     } else {
         println("The string is nil")
}
// 輸出 "The string is 'a string'"

函數

單返回值簡單函數

兩個參數一個返回值,都爲Int閉包

func thirdFunction(firstValue: Int, secondValue: Int) -> Int {
         return firstValue + secondValue
     }
thirdFunction(1, 2)

使用元組多返回值

func fourthFunction(firstValue: Int, secondValue: Int)
         -> (doubled: Int, quadrupled: Int) {
         return (firstValue * 2, secondValue * 4)
     }
fourthFunction(2, 4)

// 用數字訪問:
fourthFunction(2, 4).1 // = 16

// 其餘相同,只是使用了名字:
fourthFunction(2, 4).quadrupled // = 16

外部名稱調用

在定義函數時,能夠爲參數指定名字。當沒法立刻明白每一個參數的用途時,這一功能會非 常有用。能夠像下面這樣來定義參數名字:app

func addNumbers(firstNumber num1 : Int, toSecondNumber num2: Int) -> Int {
         return num1 + num2
}
addNumbers(firstNumber: 2, toSecondNumber: 3)  // = 5

在爲參數建立名字時,就是爲參數建立一個內部名字和一個外部名字,一個參數的內部名字應當與外部名字相同。將同一個名字輸 入兩次也沒有什麼問題,但的確有一種簡便的方式來定義一個外部名字與內部名字相同的 參數——就是在參數名以前放一個 # 符號ide

func multiplyNumbers(#firstNumber: Int, #multiplier: Int) -> Int {
         return firstNumber * multiplier
}
multiplyNumbers(firstNumber: 2, multiplier: 3)  // = 6

將函數用做變量

var numbersFunc: (Int, Int) -> Int;
// numbersFunc如今能夠存儲任何接受兩個Int並返回一個Int的函數

numbersFunc = addNumbers
numbersFunc(2, 3) // = 5

閉包closure

sort須要傳遞一個閉包做爲參數函數

var numbers = [2,4,34,6,33,1,67,20]
var numbersSorted = numbers.sort( { (first, second ) -> Bool in
    
    return first < second
})

閉包只包含一行代碼,能夠省略 return 關鍵字oop

var numbersSorted = numbers.sort( { $1 > $0})
print(numbersSorted)

若是一個閉包是函數調用中的最後一個參數,能夠將它放在括號外面。這純粹是爲 了提升可讀性,不會改變閉包的工做方式

var numbersSorted = numbers.sort(){ $1 > $0}
print(numbersSorted)

閉包放在變量裏面

var comparator = {(a: Int, b: Int) in a < b}
comparator(1, 2)  // = true

對象

定義

class Vehicle {
    var color: String?
    var maxSpeed = 80
    func description() -> String {
        return "A \(self.color) vehicle"
    }
    func travel() {
        print("Traveling at \(maxSpeed) kph")
    }
}

使用

var redVehicle = Vehicle()
redVehicle.color = "Red"
redVehicle.maxSpeed = 90
redVehicle.travel() // 輸出"Traveling at 90 kph" redVehicle.description() // = "A Red vehicle"

繼承

要重寫一個函數,要在子類中從新聲明它,並添加 override 關鍵字

class Car: Vehicle {
// 繼承類能夠重寫函數
             override func description() -> String {
                 var description = super.description()
                 return description + ", which is a car"
} }

在一個被重寫的函數中,能夠經過 super 回調該函數在父類中的版本

override func description() -> String {
         var description = super.description()
         return description + ", which is a car"
}

初始化與反初始化

class InitAndDeinitExample {
    // 指定的初始化器(也就是主初始化器)
    init() {
        print("I've been created!")
    }
    // 便捷初始化器,是調用上述指定初始化器所必需的
    convenience init (text: String) {
        self.init() // 這是必需的
        print("I was called with the convenience initializer!")
    }
    // 反初始化器
    deinit {
        print("I'm going away!")
    }
}

var example : InitAndDeinitExample?
// 使用指定的初始化器
example = InitAndDeinitExample() // 輸出"I've been created!"
example = nil // 輸出"I'm going away"
// 使用便捷初始化器
example = InitAndDeinitExample(text: "Hello")
// 輸出"I've been created!"
// 而後輸出"I was called with the convenience initializer"

建立一個能夠返回 nil 的初始化器(也稱爲能夠失敗的初始化器),就在 init 關鍵字的後面放上一個問號,並在初始化器肯定它不能成功地構造該對象時,使用 return nil:

convenience init? (value: Int) {
    self.init()
    if value > 5 {
        // 不能初始化這個對象;返回nil,表示初始化失敗 return nil
    } }

在使用一個能夠失敗的初始化器時,任何能夠在其中存儲該結果的變量都是可選的:

let failableExample = InitAndDeinitExample(value: 6)
// = nil

協議

使用協議的好處是,能夠利用 Swift 的類型體系來引用任何遵照某一給定協議的對象,我的如今理解爲是Interface概念。

protocol Blinking{
    var isBlinking:Bool{get}
    var blinkSpeed: Double { get set }
    func startBlinking(blinkSpeed: Double) -> Void
    
}

class Light:Blinking{
    var isBlinking = false
    var blinkSpeed = 1.2
    func startBlinking(blinkSpeed: Double) {
            print("now my speed is \(self.blinkSpeed)")
    }
    
}

擴展

extension Int {
         var doubled : Int {
             return self * 2
         }
         func multiplyWith(anotherNumber: Int) -> Int {
             return self * anotherNumber
} }

2.doubled  // = 4
4.multiplyWith(32) // = 128

還能夠利用擴展使一個類型遵照一個協議

extension Int : Blinking {
    var isBlinking : Bool {
        return false;
    }
    var blinkSpeed : Double {
        get {
            return 0.0; }
        set {
            // 不作任何事情
        } }
    func startBlinking(blinkSpeed : Double) {
        print("I am the integer \(self). I do not blink.")
    } }
2.isBlinking // = false
2.startBlinking(2.0) // 輸出"I am the integer 2. I do not blink."

訪問控制

在將一個方法或屬性聲明爲 public 時,App 中的全部人都能看到它:

// 可供全部人訪問
public var publicProperty = 123

//若是將一個方法或屬性聲明爲 private,那隻能在聲明它的源文件內部看到它:
// 只能在這個源文件中訪問
private var privateProperty = 123

// 僅能供本模塊訪問
// 這裏的'internal'是默認的,能夠省略 
internal var internalProperty = 123

運算符重載

相似C++的運算符重載

class Vector2D {
    var x : Float = 0.0
    var y : Float = 0.0
    init (x : Float, y: Float) {
        self.x = x
        self.y = y
    }
   
}
func +(left : Vector2D, right: Vector2D) -> Vector2D {
    let result = Vector2D(x: left.x + right.x, y: left.y + right.y)
    return result
}

let first = Vector2D(x: 2, y: 2)
let second = Vector2D(x: 4, y: 1)
let result = first + second

泛型

Swift與Java泛型相同

class Tree <T> {
    // 'T'如今能夠用做一種類型 var value : T
    var value:T
    var children : [Tree <T>] = []
    init(value : T) {
        self.value = value
    }
    func addChild(value : T) -> Tree <T> {
        var newChild = Tree<T>(value: value)
        children.append(newChild)
        reutrn newChild
    }
}


// 整數樹
let integerTree = Tree<Int>(value: 5)
// 能夠增長包含Int的子樹 
integerTree.addChild(10)
//用Swift設計程序 | 45
integerTree.addChild(5)
// 字符串樹
let stringTree = Tree<String>(value: "Hello")
stringTree.addChild("Yes")
stringTree.addChild("Internets")

字符串

比較字符串

let string1 : String = "Hello"
     let string2 : String = "Hel" + "lo"
     if string1 == string2 {
         println("The strings are equal")
  }

查找字符串

if string1.hasPrefix("H") {
         println("String begins with an H")
     }
     if string1.hasSuffix("llo") {
         println("String ends in 'llo'")
     }

數據

let stringToConvert = "Hello, Swift"
let data = stringToConvert.dataUsingEncoding(NSUTF8StringEncoding)

Swift with cocoa用Xcode開發軟件

打開Xcode 7.2

STEP1

打開Xcode新建Project選擇OSX Application

STEP2

STEP3

打開Main.storyboard,在ViewController中拖入Label

STEP4

修改ViewController.swift代碼

import Cocoa

class ViewController: NSViewController {

    @IBOutlet weak var timestamp:NSTextField!
    @IBOutlet weak var dateLabel:NSTextField!
    @IBAction func calc(sender:NSButton){
        
        //將輸入的字符串轉爲NSString
        let string = NSString(string: self.timestamp.stringValue)
        
        //轉爲double類型
        let ts:NSTimeInterval = string.doubleValue
        
        //轉換日期
        let date = NSDate(timeIntervalSince1970: ts)
        
        //日期格式化
        let dfmatter = NSDateFormatter()
        dfmatter.dateFormat="yyyy年MM月dd日"
        
        //顯示到Label
        dateLabel.stringValue = dfmatter.stringFromDate(date)
    }
    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
    }

    override var representedObject: AnyObject? {
        didSet {
        // Update the view, if already loaded.
        }
    }


}

上述的NSTextField後面的歎號,它被稱爲隱式拆封的可選類型,是一種特殊類型,指出變量可能有值,也可能爲nil。Swift運行 環境不喜歡訪問值爲nil的變量,所以Swift程序員必須知曉變量的值,尤爲在其可能爲nil時。
將變量聲明爲隱式拆封的可選類型至關於告訴Swift編譯器,你承諾在該變量的值爲nil時絕 不會訪問它。這是你與編譯器簽定的一個合約,你必須遵照。若是你不遵照,在變量爲nil時訪 問它,將引起運行階段錯誤,致使應用程序中止運行

另外也能夠開啓兩個視圖直接拖入例如:
Snip20160212_1

STEP5

連接UI與代碼部分,將TextField右鍵,選擇new referencing Outlets點加號指向ViewController,在彈出的選項裏面選擇timestamp,一樣方式選擇到label上。
Snip20160210_15

綁定按鈕的click事件
Snip20160210_16

STEP6

點擊上方的三角箭頭運行程序

Snip20160210_17

相關文章
相關標籤/搜索