Swift更新較快,現(xiàn)在語法也比較穩(wěn)定了,iOS開發(fā) Swift語言肯定是趨勢(shì),所以最近開始學(xué)習(xí)Swift,直接swift3.0 入手。
在看完swift語言之后,自己開始寫一些簡(jiǎn)單的小demo,在這個(gè)過程中發(fā)現(xiàn)一些Swift和Objecobt-C的使用差異 持續(xù)更新:
- Swift中沒有 #pragma mark 函數(shù)注釋說明,網(wǎng)上一查,Swift不支持這個(gè)了,因?yàn)?pragma mark 是屬于C的語法,swift中有了新的一些語法,如:
//MARK://FIXME://TODO
// MARK: - 生成分隔線
// MARK: 說明
如果你想自己定義//warning: 或者其他的,可以通過腳本實(shí)現(xiàn),在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/"
如下圖:

運(yùn)行之后能在左側(cè)看到警告,這個(gè)在我們實(shí)際開發(fā)項(xiàng)目中還是比較實(shí)用的,所以這個(gè)必須得加上去。

這樣項(xiàng)目開發(fā) 是不是很清楚了?
2.Optional
**Optional 是Swift中的一種特殊的類型,它本身有一個(gè)枚舉的定義,簡(jiǎn)單來說就是這個(gè)形式:
Enum Optional {
case None
case Some(Wrapped)
}
Swift在變量定義的時(shí)候 var 需要有個(gè)初始值,這是我在沒看到 Optional之前,以為是Swift的特點(diǎn), 看到Optional之后,之后可以像Object-C一樣 可以不用賦值,但需要加上?
如聲明一個(gè) Optional的Int類型的變量
var num : Int?
在引用這個(gè)Optional變量的時(shí)候,需要做特殊的處理,強(qiáng)制解包(使用!) 如下:
num = 2
let total = num! + 2
let possibleString: String? = "An optional string."
let forcedString: String = possibleString! //需要??來強(qiáng)制拆包 符合變量定義的時(shí)候有初始值
使用if let 來安全的操作Optional值,只有num存在時(shí),變量numValue才會(huì)被初始化賦值
if let numValue = num {
print(numValue)
}
else{
print("error")
}
3.defer
這個(gè)swift 新增的一個(gè)關(guān)鍵字defer 推遲執(zhí)行 看下下面例子
func testForDefer() {
print("123")
defer {
print("456")
}
print("789")
}
testForDefer()
輸出:123 789 456
這個(gè)有點(diǎn)像Java中的 try finally控制語句,在finally中的代碼塊執(zhí)行我們最后想要做的事,Swift中用defer 可以達(dá)到同樣的效果,不得不說Swift進(jìn)步很多。
4.閉包
嵌套函數(shù)
func makeIncrementor(forIncrement amount: Int) -> () -> Int {
var runningTotal = 0
func incrementor() -> Int {
runningTotal += amount
return runningTotal
}
return incrementor
}
incrementor函數(shù)引用(捕獲)了
當(dāng)前runningTotal變量,這邊的變量生命周期不會(huì)隨著函數(shù)結(jié)束而停止makeIncrementor 的返回類型為 () -> Int,這意味著返回的是一個(gè)函數(shù)
**let incrementByTen = makeIncrementor(forIncrement: 10) **
incrementByTen 不是一個(gè)Int值 : (()) -> Int
可以理解為一個(gè)無參函數(shù) ,為了返回Int 可以調(diào)用incrementByTen()
尾隨閉包:閉包必須是參數(shù)列表的最后一個(gè)參數(shù)
func followingClosure(index:Int,closure: () -> Int ){
print("1")
print(closure())
}
followingClosure(index: 100, closure: {
print("2")
return 3
})
//括號(hào)之后是個(gè)函數(shù) () -> Int 這是尾隨閉包的意義所在
followingClosure(index: 100) { () -> Int in
print("2")
return 3
}
自動(dòng)閉包
自動(dòng)閉包不接受任何參數(shù),被調(diào)用時(shí)會(huì)返回被包裝在其中的表達(dá)式的值。
var listABC = ["A","B","C"]
let listProvider = {
print("autoClosure")
listABC.remove(at: 0)
}
listProvider() //執(zhí)行這句之后 閉包內(nèi)的函數(shù)才執(zhí)行 通過這個(gè)控制執(zhí)行的時(shí) 自動(dòng)執(zhí)行代碼 是它的關(guān)鍵所在
逃逸閉包
當(dāng)一個(gè)傳入函數(shù)的閉包在函數(shù)執(zhí)行結(jié)束之后才會(huì)被調(diào)用,這樣的閉包就叫做逃逸閉包。如果一個(gè)函數(shù)的參數(shù)有一個(gè)逃逸閉包,可以在參數(shù)前加@escaping關(guān)鍵字來修飾。一個(gè)閉包是逃逸必要的條件是這個(gè)閉包需要存儲(chǔ)在函數(shù)外部
逃逸閉包一般用于異步函數(shù)的回調(diào)
官方例子
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 很像。