Swift 學習筆記

Swift更新較快,現在語法也比較穩定了,iOS開發 Swift語言肯定是趨勢,所以最近開始學習Swift,直接swift3.0 入手。

在看完swift語言之后,自己開始寫一些簡單的小demo,在這個過程中發現一些Swift和Objecobt-C的使用差異 持續更新:

  1. Swift中沒有 #pragma mark 函數注釋說明,網上一查,Swift不支持這個了,因為#pragma mark 是屬于C的語法,swift中有了新的一些語法,如://MARK: //FIXME: //TODO

// MARK: - 生成分隔線
// MARK: 說明

如果你想自己定義//warning: 或者其他的,可以通過腳本實現,在Target -> Build Phases -> + ->New Run Script Phases

TAGS="TODO:|warning:"
echo "searching ${SRCROOT} for ${TAGS}"
find "${SRCROOT}" \( -name "*.swift" \) -print0 | xargs -0 egrep --with-filename --line-number --only-matching "($TAGS).*\$" | perl -p -e "s/($TAGS)/ warning: \$1/"

如下圖:


圖1.png

運行之后能在左側看到警告,這個在我們實際開發項目中還是比較實用的,所以這個必須得加上去。


圖2.png

這樣項目開發 是不是很清楚了?

2.Optional

**Optional 是Swift中的一種特殊的類型,它本身有一個枚舉的定義,簡單來說就是這個形式:

Enum Optional {
    case None
    case Some(Wrapped)
}

Swift在變量定義的時候 var 需要有個初始值,這是我在沒看到 Optional之前,以為是Swift的特點, 看到Optional之后,之后可以像Object-C一樣 可以不用賦值,但需要加上?

如聲明一個 Optional的Int類型的變量

var num : Int?

在引用這個Optional變量的時候,需要做特殊的處理,強制解包(使用!) 如下:

num = 2
let total = num! + 2

let possibleString: String? = "An optional string."
let forcedString: String = possibleString!  //需要??來強制拆包 符合變量定義的時候有初始值

使用if let 來安全的操作Optional值,只有num存在時,變量numValue才會被初始化賦值

if let numValue = num { 
   print(numValue)
}
else{ 
   print("error")
}

3.defer
這個swift 新增的一個關鍵字defer 推遲執行 看下下面例子

func testForDefer() {
    print("123")
    defer {
        print("456")
    }
    print("789")
}
testForDefer()

輸出:123 789 456
這個有點像Java中的 try finally控制語句,在finally中的代碼塊執行我們最后想要做的事,Swift中用defer 可以達到同樣的效果,不得不說Swift進步很多。

4.閉包
嵌套函數

func makeIncrementor(forIncrement amount: Int) -> () -> Int {
    var runningTotal = 0
    func incrementor() -> Int {
        runningTotal += amount
        return runningTotal
    }
    return incrementor
}

incrementor函數引用(捕獲)了

當前runningTotal變量,這邊的變量生命周期不會隨著函數結束而停止makeIncrementor 的返回類型為 () -> Int,這意味著返回的是一個函數

**let incrementByTen = makeIncrementor(forIncrement: 10) **
incrementByTen 不是一個Int值 : (()) -> Int

可以理解為一個無參函數 ,為了返回Int 可以調用incrementByTen()

尾隨閉包:閉包必須是參數列表的最后一個參數

func followingClosure(index:Int,closure: () -> Int ){
       print("1")
      print(closure())
}
followingClosure(index: 100, closure:    {
        print("2")
        return 3
})

//括號之后是個函數 () -> Int 這是尾隨閉包的意義所在
followingClosure(index: 100) { () -> Int in
    print("2")
    return 3
}

自動閉包
自動閉包不接受任何參數,被調用時會返回被包裝在其中的表達式的值。

var listABC = ["A","B","C"]
let listProvider = { 
   print("autoClosure")
    listABC.remove(at: 0)
}
listProvider() //執行這句之后 閉包內的函數才執行 通過這個控制執行的時 自動執行代碼 是它的關鍵所在

逃逸閉包
當一個傳入函數的閉包在函數執行結束之后才會被調用,這樣的閉包就叫做逃逸閉包。如果一個函數的參數有一個逃逸閉包,可以在參數前加@escaping關鍵字來修飾。一個閉包是逃逸必要的條件是這個閉包需要存儲在函數外部

逃逸閉包一般用于異步函數的回調
官方例子

var completionHandlers: [() -> Void] = []
func someFunctionWithEscapingClosure(completionHandler: @escaping () -> Void) {
    completionHandlers.append(completionHandler)
}

func someFunctionWithNonescapingClosure(closure: () -> Void) {
    closure()
}

class SomeClass {
    var x = 10
    func doSomething() {
        someFunctionWithEscapingClosure { self.x = 100 }
        someFunctionWithNonescapingClosure { x = 200 }
    }
}

let instance = SomeClass()
instance.doSomething()
print(instance.x)
// 輸出 "200"

completionHandlers.first?()
print(instance.x)
// 輸出 "100"

例子中可以看出:
逃逸閉包類中的變量或常量必須顯示指明self,而普通的閉包可以直接使用x。
從使用的方式地和作用,是不是和Object-C中的block 很像。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容