闭包的循环引用 与 解决(三种方法)
2015-12-04 00:00
351 查看
摘要: 闭包的循环引用 与 解决(三种方法)
闭包的循环引用 与 解决(三种方法)
//******************************************************
//******************************************************
//******************************************************
闭包的循环引用
import UIKit
class ViewController: UIViewController {
// 定义完成回调属性
// 闭包的返回值可选
// var finishedCallBack: ()->()?
// 闭包属性可选
var finishedCallBack: ((html: String)->())?
override func viewDidLoad() {
super.viewDidLoad()
loadData { (html) -> () in
print(html)
print(self.view)
}
}
deinit {
print("控制器 88")
}
// 闭包应用场景:异步操作完成后,通过闭包的参数传递网络请求结果
func loadData(finished: (html: String) -> ()) {
// 1. 记录完成回调
finishedCallBack = finished
dispatch_async(dispatch_get_global_queue(0, 0)) { () -> Void in
print("模拟异步加载数据")
// 主线程回调
dispatch_async(dispatch_get_main_queue(), { () -> Void in
print("主线程回调")
// 如果回调不能在当前方法立即执行,可以通过属性记录,在需要的时候用执行
// finished(html: "<html>")
self.finishedCallBack?(html: "hahah")
})
}
}
}
//******************************************************
//******************************************************
//******************************************************
解决办法
import UIKit
class ViewController: UIViewController {
// 定义完成回调属性
// 闭包的返回值可选
// var finishedCallBack: ()->()?
// 闭包属性可选
var finishedCallBack: ((html: String)->())?
override func viewDidLoad() {
super.viewDidLoad()
// 方法三:Swift 的方法2
// [unowned self] 表示闭包中的 self 都是 assign -> 如果 self 被释放,闭包中的 self 的地址不会修改
// 与__unsafe_unretained类似,如果 self 被释放,同样会出现野指针
loadData { [unowned self] (html) -> () in
print(html)
// self? 表示对象一旦被释放,不再访问其属性或者方法
print(self.view)
}
}
func demo2() { //推荐使用
// 方法二:Swift 的方法1
// [weak self] 表示闭包中的 self 都是 弱引用
// 与 __weak 类似,如果 self 被释放,什么也不做,更安全
loadData { [weak self] (html) -> () in
print(html)
// self? 表示对象一旦被释放,不再访问其属性或者方法
print(self?.view)
}
}
// 方法一:OC 的传统方法
func demo1() {
// weak 属性在运行时可能会被改变 -> 执行对象一旦被释放,变成 nil
// weak 属性不能是 let
weak var weakSelf = self
loadData { (html) -> () in
print(html)
// 闭包中,一定要使用 self.
// weakSelf? 表示对象一旦被释放,不再访问其属性或者方法
print(weakSelf?.view)
}
}
deinit {
print("控制器 88")
}
// 闭包应用场景:异步操作完成后,通过闭包的参数传递网络请求结果
func loadData(finished: (html: String) -> ()) {
// 1. 记录完成回调
finishedCallBack = finished
dispatch_async(dispatch_get_global_queue(0, 0)) { () -> Void in
print("模拟异步加载数据")
// 主线程回调
dispatch_async(dispatch_get_main_queue(), { () -> Void in
print("主线程回调")
// 如果回调不能在当前方法立即执行,可以通过属性记录,在需要的时候用执行
// finished(html: "<html>")
self.finishedCallBack?(html: "hahah")
})
}
}
}
闭包的循环引用 与 解决(三种方法)
//******************************************************
//******************************************************
//******************************************************
闭包的循环引用
import UIKit
class ViewController: UIViewController {
// 定义完成回调属性
// 闭包的返回值可选
// var finishedCallBack: ()->()?
// 闭包属性可选
var finishedCallBack: ((html: String)->())?
override func viewDidLoad() {
super.viewDidLoad()
loadData { (html) -> () in
print(html)
print(self.view)
}
}
deinit {
print("控制器 88")
}
// 闭包应用场景:异步操作完成后,通过闭包的参数传递网络请求结果
func loadData(finished: (html: String) -> ()) {
// 1. 记录完成回调
finishedCallBack = finished
dispatch_async(dispatch_get_global_queue(0, 0)) { () -> Void in
print("模拟异步加载数据")
// 主线程回调
dispatch_async(dispatch_get_main_queue(), { () -> Void in
print("主线程回调")
// 如果回调不能在当前方法立即执行,可以通过属性记录,在需要的时候用执行
// finished(html: "<html>")
self.finishedCallBack?(html: "hahah")
})
}
}
}
//******************************************************
//******************************************************
//******************************************************
解决办法
import UIKit
class ViewController: UIViewController {
// 定义完成回调属性
// 闭包的返回值可选
// var finishedCallBack: ()->()?
// 闭包属性可选
var finishedCallBack: ((html: String)->())?
override func viewDidLoad() {
super.viewDidLoad()
// 方法三:Swift 的方法2
// [unowned self] 表示闭包中的 self 都是 assign -> 如果 self 被释放,闭包中的 self 的地址不会修改
// 与__unsafe_unretained类似,如果 self 被释放,同样会出现野指针
loadData { [unowned self] (html) -> () in
print(html)
// self? 表示对象一旦被释放,不再访问其属性或者方法
print(self.view)
}
}
func demo2() { //推荐使用
// 方法二:Swift 的方法1
// [weak self] 表示闭包中的 self 都是 弱引用
// 与 __weak 类似,如果 self 被释放,什么也不做,更安全
loadData { [weak self] (html) -> () in
print(html)
// self? 表示对象一旦被释放,不再访问其属性或者方法
print(self?.view)
}
}
// 方法一:OC 的传统方法
func demo1() {
// weak 属性在运行时可能会被改变 -> 执行对象一旦被释放,变成 nil
// weak 属性不能是 let
weak var weakSelf = self
loadData { (html) -> () in
print(html)
// 闭包中,一定要使用 self.
// weakSelf? 表示对象一旦被释放,不再访问其属性或者方法
print(weakSelf?.view)
}
}
deinit {
print("控制器 88")
}
// 闭包应用场景:异步操作完成后,通过闭包的参数传递网络请求结果
func loadData(finished: (html: String) -> ()) {
// 1. 记录完成回调
finishedCallBack = finished
dispatch_async(dispatch_get_global_queue(0, 0)) { () -> Void in
print("模拟异步加载数据")
// 主线程回调
dispatch_async(dispatch_get_main_queue(), { () -> Void in
print("主线程回调")
// 如果回调不能在当前方法立即执行,可以通过属性记录,在需要的时候用执行
// finished(html: "<html>")
self.finishedCallBack?(html: "hahah")
})
}
}
}
相关文章推荐
- 闭包的循环引用 与 解决(三种方法)
- 产品-作图工具
- Android 6.0电源管理方式
- 谈谈源码中的SparseArray
- 浅析ListView实现原理
- LruMemoryCache和LruCache
- Android Touch事件的分发机制
- 互联网+时代背景下,“90”后就业趋势
- ERROR-3:React
- linux环境下的python安装过程(含setuptools)
- Velocity快速入门——第六章 条件指令
- Velocity入门指南——第七章 循环指令
- Velocity入门指南——第八章 导入外部文件
- Velocity入门指南——第九章 其它指令
- Velocity入门指南——第十章 宏调用
- BestCoder Round #64 (div.2) HDOJ5587 Array(dfs)
- iOS开发常见问题(二)
- restful-webservice-interceptor
- 计算机存储结构以及方式
- Java length size