Swift中的闭包 , 几乎和OC中的block一模一样 , 我个人又比较偏好block , 所以觉得闭包还是蛮不错的 . 在循环引用问题上 , 解决方案也更加简洁
// HttpTool类
import UIKit
class HttpTool: NSObject {
//闭包写法 : (参数列表) -> (返回值类型)
func loadData(callBack:(jsonData:String) -> ()) {
//模拟网络请求 (因为我这里使用的是xCode低版本 , 所以方法名称具体有所不一样,但是写法都是差不多的)
dispatch_async(dispatch_get_global_queue(0, 0)) {
print("发送网络请求 -- \(NSThread.currentThread())")
//主线程更新UI
dispatch_async(dispatch_get_main_queue(), {
callBack(jsonData: "json数据")
})
}
}
//模拟网络请求二
//定义闭包类型属性,存储闭包回调操作
var backOperation:((jsonData:String) ->())? = nil
func loadMoreData(backOperation:(jsonData:String) ->() ) {
//存储操作
self.backOperation = backOperation
//子线程请求
dispatch_async(dispatch_get_global_queue(0, 0)) {
print("发送网络请求:\(NSThread.currentThread())")
//主线程回调更新UI
dispatch_async(dispatch_get_main_queue()) {
// backOperation(jsonData: "json数据")
self.backOperation?(jsonData:"json数据")
}
}
}
}
//未涉及循环引用情况 :
//创建HttpTool实例对象
let tool :HttpTool = HttpTool()
//调用模拟网络请求方法
tool.loadData { (jsonData) in
print("获取数据\(jsonData),进行主线程更新UI")
print(NSThread.currentThread())
}
//注意:这种情况已经造成了循环引用
//闭包为self.tool属性 , 故指针指向了闭包所在内存地址 . 在下述闭包中, 又访问了self的内存地址进行背景色赋值 .
//解决办法循环引用方法一: (和OC一致 ,弱化self)
weak var weakself = self
tool.loadMoreData { (jsonData) in
// weakself?的意思是:如果weakself没有值 , 后面的代码将不会执行 , 如果weakself有值 , 那么会自动将weakself进行解包,并执行后续代码
// 个人觉得这点的设计还是非常人性化的,不知道这个语法前,我就在想,如果一直需要进行if判断,然后解包, 这代码也太烂了
weakself?.view.backgroundColor = UIColor.redColor()
print("获取数据\(jsonData) --- 当前线程:\(NSThread.currentThread())")
}
//解决循环引用方法二 : (直接在大括号后,写[weak self],推荐使用)
tool.loadMoreData {[weak self] (jsonData) in
//这里的self依然变成可选类型
self?.view.backgroundColor = UIColor.greenColor()
print("获取数据\(jsonData) --- 当前线程:\(NSThread.currentThread())")
}
//解决循环引用方法三: (不推荐 , 如果self为空, 直接崩溃)
tool.loadMoreData {[unowned self] (jsonData) in
self.view.backgroundColor = UIColor.greenColor()
print("获取数据\(jsonData) --- 当前线程:\(NSThread.currentThread())")
}
}
//备注:
/* unowned 很类似于 OC中的__unsafe_unretained , 如果unowned修饰的弱引用,指针指向的对象销毁 , 指针依然指向该内存地址 , 访问僵尸对象,造成'野指针'错误
weak 就相当于OC中的 __weak ,如果weak修饰的弱引用 ,指针指向的对象销毁, 指针会立即置为nil
*/
//控制器销毁调用 , 相当于OC中的 dealloc
deinit {
print("---控制器销毁")
}
————– 补充 : 尾随闭包
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
//尾随闭包:如果闭包作为函数的最后一个参数,那么闭包可以将()省略
//写法1:
test ({ (str) in
print("\(str),world !")
})
//写法2:
test (){ (str) in
print("\(str),world !")
}
//写法3: (系统写法)
test { (str) in
print("\(str),world !")
}
}
}
//测试函数
func test(bag:(str:String) ->()) {
print("test ---")
bag(str: "hello")
}