一、有关回调
我们知道,执行函数的时候,一般都有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
""
|