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学习笔记(14)- 解决循环强引用
- 学习记录-QCheckBox使用setChecked初始设置没有信号的解决方法
- swift protocol 协议代理的使用以及解决循环引用问题
- 小胖说swift07-------- swift协议代理的使用以及解决循环引用问题
- swift协议代理的使用以及解决循环引用问题
- swift学习--闭包的循环引用解决
- swift中解决循环引用的方法
- Swift学习记录 -- 5. 循环的使用
- 不使用循环结构解决循环问题的方法
- C#学习记录(五)-------document.all使用方法
- 20100821 学习记录:VB中WebBrowser控件关于..\ieframe.dll\1'未找到之解决方法
- 解决OleDbDataReader重新获取记录时,使用GetString()方法出错的问题
- 解决OleDbDataReader重新获取记录时,使用GetString()方法出错的问题
- 使用json序列化类型为“ajax学习.DataSetComment+T_CommentDataTable”的对象时检测到循环引用。
- 有自定义控件的网站项目发布时,“不允许循环文件引用”的错误”的解决方法
- [转] Linux Oracle下sqlplus无法使用命令退格删除和历史记录的解决方法(使用rlwrap)
- 使用Hibernate插入数据后数据库没有记录的解决方法
- 解决使用VS2010时,引用外部dll时提示,无法嵌入互操作类型“……”,请改用适用的接口的解决方法
- 生成动态库so的方法|解决NDK r5b引用静态库失效的问题|在NDK的Nactive代码中使用Android Log的方法|生成Native java头文件