1、有關回調git
咱們知道,執行函數的時候,通常都有return做爲返回參數了,那有return了爲何還要回調呢?github
回調是爲了實現異步的返回,在某些特殊的狀況下,好比你執行的函數是一個長時間運行的函數,並不能直接返回給你結果,爲了避免影響源程序其餘步驟的執行,你得繼續執行下去,等那邊產生結果了再「主動告訴你」結果是什麼。swift
其原理不外乎:A調用B中函數,傳遞參數和自身指針,B執行完成再經過傳遞過來的指針從新調用A中函數。閉包
在iOS開發中,實現回調的方式有:Delegate和Block。前者用變量指針實現,後者用函數指針實現。異步
假如我如今有一個processData的類用來處理數據,處理完以後回調給主要的Class。ide
2、Swift中實現回調函數
1.代理模式:利用protocol+引用變量代理
processData.swift指針
// // ProcessData.swift import UIKit //定義協議 protocol callBackDelegate { func callbackDelegatefuc(backMsg:String) } class ProcessData: NSObject{ //定義一個符合改協議的代理對象 var delegate:callBackDelegate? func processMethod(cmdStr:String?){ if((delegate) != nil){ delegate?.callbackDelegatefuc("backMsg---by delegate") } } }
ViewController.swift對象
// // ViewController.swift import UIKit //繼承該協議 class ViewController: UIViewController,callBackDelegate{ override func viewDidLoad() { super.viewDidLoad() let process=ProcessData() //把process的delegate變量指針指向本身,那樣process就能調用本身類裏的函數了 process.delegate=self //執行函數 process.processMethod("startProcess") } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() } //delegate回調 func callbackDelegatefuc(backMsg:String){ print(backMsg) } }
2.利用閉包實現:
閉包在Objective-C中被稱爲Block,在Swift中被成爲Closure(在Java中稱爲Lambda)
2.1利用閉包變量實現回調
processData.swift
// // ProcessData.swift import UIKit class ProcessData: NSObject{ //定義block typealias fucBlock = (backMsg :String) ->() //建立block變量 var blockproerty:fucBlock! func processMethod(cmdStr:String?){ if let _ = blockproerty{ blockproerty(backMsg: "backMsg---by block property") } } }
ViewController.swift
// // ViewController.swift import UIKit class ViewController: UIViewController{ override func viewDidLoad() { super.viewDidLoad() let process=ProcessData() //block回調 process.blockproerty={ (backMsg) in print(backMsg) } //執行函數 process.processMethod("processStart") } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() } }
2.2 把閉包寫入函數做參數實現快速回調,可見這是一種代碼最爲簡潔的方案
processData.swift
// // ProcessData.swift import UIKit class ProcessData: NSObject{ //定義block typealias fucBlock = (backMsg :String) ->() func processWithBlock(cmdStr:String?,blockProperty:fucBlock){ blockProperty(backMsg :"backMsg---by block inside func") } }
ViewController.swift
// // ViewController.swift import UIKit class ViewController: UIViewController{ override func viewDidLoad() { super.viewDidLoad() let process=ProcessData() //函數內回調 process.processWithBlock("bbb") { (backMsg) in print(backMsg) } } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() } }
PS:若是Block帶返回值的狀況下,Block是這樣定義和調用的
//定義block typealias fucBlock = (backMsg :String) ->(String)
//函數內回調 process.processWithBlock("bbb") { (backMsg) ->(String) in print(backMsg) return "get msg" }
2.3.剛使用的typealias把block給定義給一個變量了,如今直接代替進去就能夠了,而且我給函數再加個String類型返回值。。
processData.swift
func processWithBlock(cmdStr:String?,blockProperty:(backMsg :String) ->())->(String){ blockProperty(backMsg :"backMsg---by block inside func") return "" }