Swift 用Delegate和Block实现回调的Demo

转载 RETHINK的文章

一、有关回调

我们知道,执行函数的时候,一般都有return作为返回参数了,那有return了为什么还要回调呢?

回调是为了实现异步的返回,在某些特殊的情况下,比如你执行的函数是一个长时间运行的函数,并不能直接返回给你结果,为了不影响源程序其他步骤的执行,你得继续执行下去,等那边产生结果了再“主动告诉你”结果是什么。

其原理不外乎:A调用B中函数,传递参数和自身指针,B执行完成再通过传递过来的指针重新调用A中函数。

在iOS开发中,实现回调的方式有:Delegate和Block。前者用变量指针实现,后者用函数指针实现。

假如我现在有一个processData的类用来处理数据,处理完之后回调给主要的Class。

 

二、Swift中实现回调

1.代理模式:利用protocol+引用变量

processData.swift

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//
//  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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
//
//  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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//
//  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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//
//  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

1
2
3
4
5
6
7
8
9
10
11
12
13
//
//  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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//
//  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是这样定义和调用的

1
2
//定义block
     typealias fucBlock = (backMsg :String) ->(String)

 

1
2
3
4
5
//函数内回调
         process.processWithBlock( "bbb" ) { (backMsg) ->(String) in
             print(backMsg)
             return  "get msg"
        

 

 2.3.刚使用的typealias把block给定义给一个变量了,现在直接代替进去就可以了,并且我给函数再加个String类型返回值。。

processData.swift

1
2
3
4
func processWithBlock(cmdStr:String?,blockProperty:(backMsg :String) ->())->(String){
         blockProperty(backMsg : "backMsg---by block inside func" )
         return  ""
    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值