您的位置:首页 > 移动开发 > Swift

Swift学习记录 -- 14.闭包的使用和解决循环引用方法

2016-10-03 17:56 507 查看
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")
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  闭包 swift class
相关文章推荐