Swift更新較快,現在語法也比較穩定了,iOS開發 Swift語言肯定是趨勢,所以最近開始學習Swift,直接swift3.0 入手。
在看完swift語言之后,自己開始寫一些簡單的小demo,在這個過程中發現一些Swift和Objecobt-C的使用差異 持續更新:
- 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/"
如下圖:
運行之后能在左側看到警告,這個在我們實際開發項目中還是比較實用的,所以這個必須得加上去。
這樣項目開發 是不是很清楚了?
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 很像。