標籤:八卦 關心 方式 變化 寫法 exe sleep 指標 sum
函數的定義
1.函數的基礎寫法
func 函數名(形參列表)->傳回值類型
例: func sum(x:int ,y:int) -> int{
return x+y
}
print(sun(x:10,y:50))
2.外部參數的使用,就是在形參前加一個名字,外部參數不會影響函數內部細節,外部參數會讓外部調用看起來更加的直觀
例:func sum(num1 x:int ,num2 y:int )-> int{
return x+y
}
print(sum(num1:30,num2:40))
使用“_”可以替代不關心的展示方式,常見的還有for迴圈中”i”如果沒有用到的情況向,可以用“_”代替
func sun(_ x:int ,_ y:int )-> int{
return x+y
}
print(sum(30,40))
3.預設值:通過給參數設定預設值,在調用的時候,可以任意組合參數,如果不指定就使用預設值。但是在OC中是不能實現的,需要定義多個函數
例 :func sum(x:int=1,y:int=2)-> int{
return x+y
}
print(sum())
print(sum(x:10,y:10))
print(sum(x:10))
…
4.無傳回值的情況:主要用在閉包
例: func demo() {}
func demo1() ->() {}
func demo2() ->void {}
閉包
1.閉包的定義:類似於OC的block,但是比block應用更廣泛
OC中block是匿名的函數
swift中函數是特殊的閉包
1.提前準備好的代碼
2.在需要的時候執行
3.可以當做參數傳遞
例1:OC中是不能實現的函數賦值
func sum(x:int=1,y:int=2)-> int{
return x+y
}
let f = sum
print(f(x:20,y:40))
例2:簡單的閉包
沒有參數和傳回值的函數b1 (此情況下可以省略參數和傳回值,包括”in”)
let b1 = {
print(“hello word”)
}
執行閉包
b1()
例3:帶參數的閉包
閉包中,參數,傳回值,實現代碼都是寫在{}中
{形參列表->傳回值 in 實現代碼}
需要用 “in” 來分割定義和實現
let b2 = {
(x:int) ->() in
print(x)
}
b2(100)
例4:帶參數和傳回值的閉包
let b3 = {
(x:int) -> int in
return x+200
}
print(b3(1111))
2.swift中GCD的使用方法
1.GCD:將任務添加到隊列,指定執行任務的函數
2.翻譯:隊列調度任務(block/閉包),以同步/非同步 的方式來執行
例:func loadData() ->(){
DispatchQueue.global().async{
print(“耗時操作 \(Thread.current())”)
DispatchQueue.main.async(execute:{
print(“主線程更新 ui \(Thread.current())”)
})
}
}
3.在非同步執行任務,擷取結果,通過 block/閉包 回調。 閉包的應用情境和block完全一致
格式定義特點
1.參數 -> 傳回值
2. loadData(completion: (result : [String]) ->()) -> () 中(completion: (result : [String]) ->()) 參數,後面是傳回值。
3.completion: (result : [String]) ->() 中 (result : [String]) 是參數 後面是傳回值
例:func loadData(completion: (result : [String]) ->() ) ->(){
DispatchQueue.global().async{
print(“耗時操作 \(Thread.current())”)
Thread.sleep(forTimeInterval:1.0)
let json = [“頭條”,”八卦”,”天氣”]
DispatchQueue.main.async(execute:{
print(“主線程更新 ui \(Thread.current())”)
//執行閉包
completion(result: json)
})
}
}
調用
loadData{
(result) in
print(“擷取成功 \(result)”)
}
4.尾隨閉包:如果函數的最後一個參數是閉包,函數參數可以提前結束,最後一個參數直接使用{}封裝閉包的代碼(3的例子)
原始的調用方法(按照函數本身編寫的結果)
loadData(
completion:{(result)->() in
print(“擷取成功 \(result)”)
}
)
嵌套的尾隨閉包是(系統)不會自動提示尾隨閉包,例如2中的例子。當然也可以手動刪除多餘的來再次寫成尾隨閉包的樣式,方便閱讀
func loadData() ->(){
DispatchQueue.global().async{
print(“耗時操作 \(Thread.current())”)
DispatchQueue.main.async{
print(“主線程更新 ui \(Thread.current())”)
}
}
}
5.在OC中可以用{} 來區分範圍。但是在swift中是不行的,swift中遇到{}可能會識別為閉包
6.swift中的迴圈應用:
1.使用OC的方式
weak var weakSelf = self
loadData{
print(weakSelf?.view)
}
細節1:要使用var修飾 不能使用let 。 因為weak可能在運行時被修改。weak指向的對象一旦被釋放,會自動化佈建為nil ,所有不能為let
細節2:?(可選解包)通常用於單純發送訊息,沒有計算 !(強行解包) 強行解包必須有值,如果沒有會造成崩潰,通常用於計算
2.Swift推薦方法
loadData{
[weak self] in
print(self?.view)
}
[weak self] 表示閉包中所有的self都是若引用,注意解包
3.Swift的一個特殊方法(不建議使用)
loadData{
[unowned self] in
print(self?.view)
}
[unowned self] 表示閉包中所有的都是 assign的,不會強引用。但是對象釋放指標地址不會變化,如果對象被釋放,繼續調用就會造成野指標的問題
7. [weak self ]是閉包整self的弱引用,如果self被釋放,會自動化佈建為nil,與OC中的 __weak等效
[unowned self] 是閉包中的self 的assign的 ,如果self被釋放,指標地址保持不變,會出現野指標的錯誤,與OC中的 __unsafe_unretained 等效
//demo:https://github.com/fushengit/Learn-Swift
Swift學習(2函數閉包)