Swift更新較快担猛,現(xiàn)在語(yǔ)法也比較穩(wěn)定了擂涛,iOS開(kāi)發(fā) Swift語(yǔ)言肯定是趨勢(shì),所以最近開(kāi)始學(xué)習(xí)Swift已旧,直接swift3.0 入手秸苗。
在看完swift語(yǔ)言之后,自己開(kāi)始寫(xiě)一些簡(jiǎn)單的小demo运褪,在這個(gè)過(guò)程中發(fā)現(xiàn)一些Swift和Objecobt-C的使用差異 持續(xù)更新:
- Swift中沒(méi)有 #pragma mark 函數(shù)注釋說(shuō)明惊楼,網(wǎng)上一查玖瘸,Swift不支持這個(gè)了,因?yàn)?pragma mark 是屬于C的語(yǔ)法檀咙,swift中有了新的一些語(yǔ)法雅倒,如:
//MARK:
//FIXME:
//TODO
// MARK: - 生成分隔線
// MARK: 說(shuō)明
如果你想自己定義//warning: 或者其他的,可以通過(guò)腳本實(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í)際開(kāi)發(fā)項(xiàng)目中還是比較實(shí)用的,所以這個(gè)必須得加上去棕诵。
這樣項(xiàng)目開(kāi)發(fā) 是不是很清楚了裁良?
2.Optional
**Optional 是Swift中的一種特殊的類(lèi)型,它本身有一個(gè)枚舉的定義校套,簡(jiǎn)單來(lái)說(shuō)就是這個(gè)形式:
Enum Optional {
case None
case Some(Wrapped)
}
Swift在變量定義的時(shí)候 var 需要有個(gè)初始值价脾,這是我在沒(méi)看到 Optional之前,以為是Swift的特點(diǎn)笛匙, 看到Optional之后侨把,之后可以像Object-C一樣 可以不用賦值,但需要加上?
如聲明一個(gè) Optional的Int類(lèi)型的變量
var num : Int?
在引用這個(gè)Optional變量的時(shí)候妹孙,需要做特殊的處理座硕,強(qiáng)制解包(使用!) 如下:
num = 2
let total = num! + 2
let possibleString: String? = "An optional string."
let forcedString: String = possibleString! //需要??來(lái)強(qiáng)制拆包 符合變量定義的時(shí)候有初始值
使用if let
來(lái)安全的操作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控制語(yǔ)句,在finally中的代碼塊執(zhí)行我們最后想要做的事机隙,Swift中用defer 可以達(dá)到同樣的效果蜘拉,不得不說(shuō)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
的返回類(lèi)型為 () -> Int,這意味著返回的是一個(gè)函數(shù)
**let incrementByTen = makeIncrementor(forIncrement: 10) **
incrementByTen
不是一個(gè)Int值 : (()) -> Int
可以理解為一個(gè)無(wú)參函數(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í)行 通過(guò)這個(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)鍵字來(lái)修飾稍味。一個(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"
例子中可以看出:
逃逸閉包類(lèi)中的變量或常量必須顯示指明self,而普通的閉包可以直接使用x荠卷。
從使用的方式地和作用模庐,是不是和Object-C中的block 很像。