Swift關鍵詞簡介
我們會經??吹紷autoclosure, @noescape等關鍵詞,下面就來簡單的說下他們的作用。
@noescape
- 用來修飾函數(shù)的閉包參數(shù),意思是說該閉包的生命周期比函數(shù)要短,只能在函數(shù)中使用,也不能將其存儲在變量中。如圖,會報錯。

- 使用@noescape,編譯器會進一步的優(yōu)化你的代碼,帶來小小的性能提升。
- 在其修飾的閉包內,可以不用self關鍵字,也不會捕獲變量,就是說可以不用weak之類的來避免循環(huán)引用。因為在函數(shù)執(zhí)行完時,closure也會被銷毀。
- 如果將此閉包傳給A函數(shù)作為參數(shù),其參數(shù)也必須由@noesapce修飾。
@autoclosure
1.同樣是用來修飾函數(shù)的閉包參數(shù),使用@autoclosure之后將會自動有@noescape的作用。顧名思義,就是將傳入的參數(shù)自動轉換成閉包,而不用我們自己來傳一個嚴格格式的閉包進去。
show(msg: String, @autoclosure ifTrue: () -> Bool){
if ifTrue(){
println(msg)
}
}
func example1(){
let age = 200
// 傳入age > 140,會自動轉換成閉包
show(msg: "You are too old", ifTrue: age > 140)
}
2.只能用于沒有參數(shù)的閉包,并且返回值不能是元組。
3.因為@autoclosure會帶有@noescape的特性,所以如果我們需要變量可以存儲閉包時,可以這樣做。@autoclosure(escaping)
func test(@autoclosure(escaping) block: () -> () ) {
let t: () -> () = block
t()
}
lazy var
lazy關鍵字是指變量用到時才去計算。
1、static,global的變量都是lazy的。
2、lazy的變量用閉包進行初始化??梢灾苯邮褂胹elf,并且也不會引起循環(huán)引用。在使用閉包時,已經自動轉成了@noescape,所以不會捕獲self。
lazy var b: Int = {
self.test4()
}()
// 也可以這樣寫,去掉閉包
lazy var c: Int = self.test4()
func test4() -> Int {
return 2
}
3、lazy sequence,collection
struct p4 {
static func f1() {
func double(x: Int) -> Int {
print("double \(x)")
return 2 * x
}
func increment(x: Int) -> Int {
print("increment \(x)")
return 1 + x
}
let array = [1, 2, 3, 4]
let r1 = array.lazy.map(increment).map(double)
print(r1[2])
let r2 = array.map(increment).map(double)
print(r2[2])
}
}
r1的結果:
increment 3
double 4
8
說明使用lazy后,只是將r1[2]取出來,然后做increment和double,不需要遍歷array,減少了不必要的計算。
======
r2的結果是:
increment 1
increment 2
increment 3
increment 4
double 2
double 3
double 4
double 5
8
不使用lazy的話,array會遍歷2次。
可變參數(shù)
func test5(data: Any...) {
for obj in data {
print("\(obj)")
}
}
dynamic
將變量或者方法聲明為dynamic,即可以使用oc的runtime,動態(tài)派發(fā),比如swizzled,replace method,KVO等等。
class Test {
dynamic var a: Int = 0
}
dynamic func test1() {
}
}
交換方法代碼如下:
import UIKit
?
class AwesomeClass {
dynamic func originalFunction() -> String {
return "originalFunction"
}
dynamic func swizzledFunction() -> String {
return "swizzledFunction"
}
}
?
let awesomeObject = AwesomeClass()
?
print(awesomeObject.originalFunction()) // prints: "originalFunction"
?
let aClass = AwesomeClass.self
let originalMethod = class_getInstanceMethod(aClass, "originalFunction")
let swizzledMethod = class_getInstanceMethod(aClass, "swizzledFunction")
method_exchangeImplementations(originalMethod, swizzledMethod)
?
print(awesomeObject.originalFunction()) // prints: "swizzledFunction"
loop label
當有2層for循環(huán),當我們要打破最外層的循環(huán)時,要怎么做呢?直接break,只能打破最里層的循環(huán)。
loop標簽就派上用場了。
func test() {
firstLoop: for i in 1...3 {
secondLoop: for j in 2...4 {
print("i+j=\(i+j)")
if (i + j == 6) {
break firstLoop
}
}
}
}