Swift 用Delegate和Block實現回調的Demo

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 ""
    }

 

 

 

swift:https://github.com/rayshen/SwiftClosure

oc:https://github.com/rayshen/callbackDemo

相關文章
相關標籤/搜索